<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Pembayaran_pelatihan extends CI_Controller
{
    /* ==============================
     * KONSTAN
     * ============================== */
    const JENIS_KEY   = 'pelatihan';   // key di tabel biaya
    const JENIS_LABEL = 'Pelatihan';   // label jenis pada pembayaran/ledger

    // mapping status siswa (ikuti punyamu)
    const STATUS_SISWA_AKTIF   = 2;
    const STATUS_SISWA_DITOLAK = 5;

    public function __construct()
    {
        parent::__construct();
        check_login();

        // Models
        $this->load->model('Pembayaran_model',      'pembayaran'); // table: pembayaran
        $this->load->model('PembayaranSiswa_model', 'ledger');     // table: pembayaransiswa
        $this->load->model('Biaya_model',           'biaya');
        $this->load->model('Siswa_model',           'siswa');

        // Libs & helpers
        $this->load->library(['form_validation','upload','session','email']);
        $this->load->helper(['form','url','pdf']); // rupiah(), terbilang_id(), doc_number()
    }

    /* ==============================
     * AREA SISWA
     * ============================== */

    /** Halaman form + ringkasan & riwayat pembayaran */
    public function index()
    {
        check_role([3]); // role siswa

        $user_id  = (int) $this->session->userdata('UserID');   // wajib ada
        $siswa_id = (string) ($this->session->userdata('SiswaID') ?? ''); // bisa kosong

        $biaya       = $this->biaya->get_current(self::JENIS_KEY);
        $total_biaya = $biaya ? (float)$biaya->Nominal : 0.0;

        if ($siswa_id !== '') {
            // Sudah punya SiswaID → riwayat & ledger by siswa
            $riwayat     = $this->pembayaran->get_by_siswa($siswa_id, self::JENIS_LABEL);
            $total_bayar = (float)$this->ledger->sum_nominal_by_siswa($siswa_id, self::JENIS_LABEL);
            $ledger_rows = $this->ledger->get_ledger_by_siswa($siswa_id, self::JENIS_LABEL);
        } else {
            // Calon → riwayat by user, ledger kosong
            $riwayat     = $this->pembayaran->get_by_user($user_id, self::JENIS_LABEL);
            $total_bayar = 0.0;
            $ledger_rows = [];
        }

        $data = [
            'title'        => 'Pembayaran Pelatihan HSI',
            'riwayat'      => $riwayat,
            'ledger'       => $ledger_rows,
            'total_bayar'  => $total_bayar,
            'total_biaya'  => $total_biaya,
            'sisa_tagihan' => max(0, $total_biaya - $total_bayar),
        ];
        $this->load->view('pembayaran/pelatihan_index', $data);
    }

    /** Siswa submit bukti pembayaran (Status = Pending) */
    public function submit()
    {
        check_role([3]);

        $user_id  = (int) $this->session->userdata('UserID');
        $siswa_id = (string) ($this->session->userdata('SiswaID') ?? '');

        // Validasi
        $this->form_validation->set_rules('JumlahBayar', 'Jumlah Bayar', 'required|numeric|greater_than[0]');
        $this->form_validation->set_rules('MetodeBayar', 'Metode Bayar', 'required');

        if (!$this->form_validation->run()) {
            $this->session->set_flashdata('error', strip_tags(validation_errors()));
            return redirect('pembayaran_pelatihan');
        }

        // Snapshot nama (siswa.NamaLengkap → fallback users.Username)
        $snap        = $this->_current_user_snapshot($user_id);
        $namaLengkap = $snap['nama'] ?: '';

        // Upload bukti (optional)
        $config = [
            'upload_path'   => FCPATH.'uploads/bukti_transfer/',
            'allowed_types' => 'jpg|jpeg|png|pdf',
            'max_size'      => 4096,
            'encrypt_name'  => TRUE,
        ];
        if (!is_dir($config['upload_path'])) @mkdir($config['upload_path'], 0777, true);
        $this->upload->initialize($config);

        $bukti = null;
        if (!empty($_FILES['BuktiTransfer']['name'])) {
            if (!$this->upload->do_upload('BuktiTransfer')) {
                $this->session->set_flashdata('error', $this->upload->display_errors('', ''));
                return redirect('pembayaran_pelatihan');
            }
            $bukti = $this->upload->data('file_name');
        }

        // Payload INSERT
        $payload = [
            'UserID'        => $user_id,
            'SiswaID'       => $siswa_id !== '' ? $siswa_id : null, // NULL (bukan string kosong)
            'NamaLengkap'   => $namaLengkap,
            'JumlahBayar'   => (float)$this->input->post('JumlahBayar', true),
            'MetodeBayar'   => $this->input->post('MetodeBayar', true),
            'BuktiTransfer' => $bukti,
            'StatusBayar'   => 'Pending',
            'Jenis'         => self::JENIS_LABEL, // model akan map ke Jenis/JenisPembayaran
            'TanggalBayar'  => date('Y-m-d H:i:s'),
        ];

        $this->db->trans_begin();
        $this->pembayaran->create_pending($payload);

        if (!$this->db->trans_status()) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error', 'Gagal menyimpan pembayaran.');
        } else {
            $this->db->trans_commit();
            $this->session->set_flashdata('success', 'Pembayaran dikirim. Menunggu verifikasi admin.');
        }
        return redirect('pembayaran_pelatihan');
    }

 /* ==============================
 * AREA ADMIN
 * ============================== */

public function admin() { return $this->admin_index(); }

/** Ringkasan semua siswa/calon HSI */
public function admin_index()
{
    check_role([1]); // Admin1

    // Biaya resmi pelatihan (boleh 0 kalau belum di-set)
    $biaya   = $this->biaya->get_current(self::JENIS_KEY);
    $nominal = $biaya ? (float)$biaya->Nominal : 0.0;

    $rows  = [];
    $list  = $this->siswa->get_all_hsi_with_calon();   // pastikan mengembalikan: UserID, SiswaID, NamaLengkap, NamaStatus (opsional)

    foreach ($list as $s) {
        $sid         = !empty($s->SiswaID) ? (string)$s->SiswaID : null;
        $total_bayar = $sid ? (float)$this->ledger->sum_nominal_by_siswa($sid, self::JENIS_LABEL) : 0.0;
        $sisa        = max(0, $nominal - $total_bayar);

        // Status dari DB (kalau ada), pakai NamaStatus saja — JANGAN pakai StatusID
        $status_db = strtolower((string)($s->NamaStatus ?? ''));

        // Normalisasi status untuk tampilan
        if (strpos($status_db, 'tolak') !== false || $status_db === 'rejected') {
            $statusText = 'Ditolak';
        } elseif ($sid) {
            // Sudah punya SiswaID -> siswa HSI
            $statusText = ($nominal > 0 && $sisa <= 0) ? 'Aktif' : 'Menunggu Pembayaran';
        } else {
            // Belum punya SiswaID -> calon
            $statusText = 'Calon';
        }

        $rows[] = [
            'UserID'      => (int)($s->UserID ?? 0),
            'SiswaID'     => $sid ?: '',
            'NamaLengkap' => $s->NamaLengkap ?? ($s->Username ?? '-'),
            'Status'      => $s->NamaStatus ?? '',   // raw (kalau mau ditampilkan apa adanya)
            'StatusText'  => $statusText,            // yang dipakai view untuk badge
            'TotalBiaya'  => $nominal,
            'TotalBayar'  => $total_bayar,
            'SisaTagihan' => $sisa,
        ];
    }

    $data = [
        'title' => 'Admin - Pembayaran Pelatihan',
        'siswa' => $rows,
    ];
    $this->load->view('pembayaran/admin_pelatihan', $data);
}

    /** Detail transaksi (param = SiswaID HSIxxxxx atau UserID numeric) */
    public function detail($id = null)
    {
        check_role([1]);

        if ($id === null || $id === '') {
            $this->session->set_flashdata('error', 'ID siswa tidak ditemukan.');
            return redirect('pembayaran_pelatihan/admin');
        }

        // SiswaID (prefix huruf) vs UserID (numeric)
        $siswa = preg_match('/^[A-Za-z]/', (string)$id)
            ? $this->siswa->get_by_id($id, null)     // by SiswaID
            : $this->siswa->get_by_id(null, $id);    // by UserID

        if (!$siswa) show_error('Siswa tidak ditemukan.', 404);

        // cek apakah kolom jenis ada
        $cols      = array_map('strtolower', $this->db->list_fields('pembayaran'));
        $has_jenis = in_array('jenis', $cols, true) || in_array('jenispembayaran', $cols, true);

        // query transaksi: fallback by UserID jika SiswaID masih kosong
        $qb = $this->db->from('pembayaran')
                       ->order_by($this->_safe_order_col('pembayaran'), 'DESC');

        if (!empty($siswa->SiswaID)) {
            $qb->where('SiswaID', $siswa->SiswaID);
        } else {
            $qb->where('UserID', (int)$siswa->UserID);
        }

        if ($has_jenis) {
            $qb->group_start()
                  ->where('Jenis', self::JENIS_LABEL)
                  ->or_where('JenisPembayaran', self::JENIS_LABEL)
               ->group_end();
        }

        $transaksi = $qb->get()->result();

        $data = [
            'title'     => 'Detail Pembayaran Pelatihan',
            'siswa'     => $siswa,
            'transaksi' => $transaksi,
        ];
        $this->load->view('pembayaran/detail_pelatihan', $data);
    }

    /**
     * APPROVE transaksi (by PembayaranID)
     * - Auto generate SiswaID untuk calon (sekali saja)
     * - Update sumber (pembayaran) → Approved (ApprovedBy/ApprovedAt)
     * - Insert ke ledger (pembayaransiswa)
     * - Recalc status siswa
     * - Kirim Kwitansi (PDF) via email
     */
    public function approve($pembayaran_id)
    {
        check_role([1,2]);

        // Ambil row sumber + fallback siswa via SiswaID OR UserID
        $row = $this->db->select('
                        p.*,
                        u.Email,
                        COALESCE(s.NamaLengkap, u.Username) AS Nama,
                        s.SiswaID AS SiswaID_S,
                        s.UserID  AS SUserID,
                        l.NamaLPK AS AsalLPK
                    ')
                    ->from('pembayaran p')
                    ->join('users u', 'u.UserID = p.UserID', 'left')
                    ->join('siswa s','s.SiswaID = p.SiswaID OR s.UserID = p.UserID','left')
                    ->join('lpk l', 'l.LPKID = s.LPKID', 'left')
                    ->where('p.PembayaranID', (int)$pembayaran_id)
                    ->limit(1)
                    ->get()->row();

        if (!$row) show_error('Pembayaran tidak ditemukan.', 404);

        $status   = strtolower((string)($row->StatusBayar ?? ''));
        $siswa_id = (string)($row->SiswaID ?: $row->SiswaID_S ?: '');
        $user_id  = (int)   ($row->SUserID ?: $row->UserID ?: 0);

        if ($status !== 'pending') {
            show_error('Pembayaran sudah diproses.');
        }

        $admin_id = (int) $this->session->userdata('UserID'); // simpan sebagai ApprovedBy

        $this->db->trans_begin();

        // Auto-assign SiswaID untuk calon
        if ($siswa_id === '' && $user_id > 0) {
            $new_id = $this->_generate_siswa_id();
            $this->db->where('UserID', $user_id)->update('siswa', [
                'SiswaID'  => $new_id,
                'StatusID' => self::STATUS_SISWA_AKTIF
            ]);
            $siswa_id = $new_id;

            // sinkron ke sumber pembayaran
            $this->db->where('PembayaranID', (int)$pembayaran_id)
                     ->update('pembayaran', ['SiswaID' => $new_id]);
        }

        // sumber -> Approved (simpen ApprovedBy/ApprovedAt di model)
        $this->pembayaran->approve((int)$pembayaran_id, $admin_id);

        // siapkan properti untuk ledger
        $row->SiswaID     = $siswa_id;
        $row->UserID      = $user_id;          // FK ledger ke users (via siswa.UserID)
        $row->StatusBayar = 'Approved';

        // insert ledger (signature: ($pembayaran_row, $student_user_id, $jenis_label))
        $this->ledger->insert_from_pembayaran($row, $user_id, self::JENIS_LABEL);

        // recalc status siswa (aktif kalau lunas)
        $this->_recalculate_and_update_status($siswa_id);

        if (!$this->db->trans_status()) {
            $this->db->trans_rollback();
            $this->session->set_flashdata('error','Gagal approve pembayaran.');
            return redirect('pembayaran_pelatihan/admin');
        }

        $this->db->trans_commit();
        $this->session->set_flashdata('success','Pembayaran di-approve.');

        // kirim kwitansi (jika gagal kirim, tidak rollback)
        @ $this->_send_kwitansi_after_approve((int)$pembayaran_id);

        return redirect('pembayaran_pelatihan/admin');
    }

/** REJECT siswa langsung (ubah status) */
  // controllers/Pembayaran_pelatihan.php
public function reject($pembayaran_id = null)
{
    check_role([1,2]);

    $id = (int)($pembayaran_id ?? 0);
    if ($id <= 0) $id = (int)$this->input->post('pembayaran_id');

    if ($id <= 0) {
        $this->session->set_flashdata('error','ID pembayaran tidak valid.');
        return redirect('pembayaran_pelatihan/admin');
    }
    if (strtoupper($this->input->method(TRUE)) !== 'POST') {
        $this->session->set_flashdata('error','Aksi ditolak. Gunakan tombol Reject (POST).');
        return redirect('pembayaran_pelatihan/detail/'.$id);
    }

    $row = $this->pembayaran->get_by_id($id);
    if (!$row) {
        $this->session->set_flashdata('error','Pembayaran tidak ditemukan.');
        return redirect('pembayaran_pelatihan/admin');
    }

    $redir_id = !empty($row->SiswaID) ? $row->SiswaID : (int)$row->UserID;

    if (strtolower((string)$row->StatusBayar) !== 'pending') {
        $this->session->set_flashdata('error','Pembayaran sudah diproses.');
        return redirect('pembayaran_pelatihan/detail/'.$redir_id);
    }

    $alasan   = trim((string)$this->input->post('alasan'));
    $admin_id = (int)($this->session->userdata('UserID')
           ?? $this->session->userdata('AdminID')
           ?? 0);

    $this->db->trans_begin();

    $ok = $this->pembayaran->reject($id, $alasan, $admin_id);

    // safety: kalau masih pending, paksa update
    if ($ok) {
        $after = $this->db->select('StatusBayar')->from('pembayaran')
                 ->where('PembayaranID',$id)->get()->row();
        if (!$after || strtolower($after->StatusBayar) === 'pending') {
            $this->db->where('PembayaranID',$id)->update('pembayaran',[
                'StatusBayar' => 'Rejected',
                'ApprovedAt'  => date('Y-m-d H:i:s'),
                'ApprovedBy'  => $admin_id
            ]);
        }
    }

    if (!$this->db->trans_status()) {
        $this->db->trans_rollback();
        $this->session->set_flashdata('error','Gagal menolak pembayaran.');
    } else {
        $this->db->trans_commit();
        $this->session->set_flashdata('success','Pembayaran ditolak.');
    }

    return redirect('pembayaran_pelatihan/detail/'.$redir_id);
}


// ============================
// Print Invoice (A4 - Dompdf)
// ============================
public function print_invoice($pembayaran_id)
{
    check_role([1,2]);

    // Ambil konteks penerima + relasi LPK
    $p = $this->db->select('
                p.PembayaranID, p.UserID,
                u.Email, u.Username, u.Phone,
                s.SiswaID, s.NamaLengkap, s.NoHP,
                l.NamaLPK
            ')
        ->from('pembayaran p')
        ->join('users u','u.UserID = p.UserID','left')
        ->join('siswa s','s.UserID = u.UserID','left')
        ->join('lpk l','l.LPKID = s.LPKID','left')
        ->where('p.PembayaranID', (int)$pembayaran_id)
        ->limit(1)->get()->row();

    if (!$p) show_error('Data pembayaran tidak ditemukan.', 404);

    // Biaya resmi pelatihan
    $biaya   = $this->biaya->get_current(self::JENIS_KEY);
    $nominal = $biaya ? (float)$biaya->Nominal : 0.0;

    // Total yang sudah dibayar (kalau sudah punya SiswaID), hanya jenis "Pelatihan"
    $sudah_bayar = 0.0;
    if (!empty($p->SiswaID)) {
        // pastikan PembayaranSiswa_model sdh diload di __construct sebagai $this->ledger
        $sudah_bayar = (float)$this->ledger->sum_nominal_by_siswa($p->SiswaID, self::JENIS_LABEL);
    }
    $belum_bayar = max(0.0, $nominal - $sudah_bayar);

    // Nomor invoice stabil per user
    $no_inv = doc_number('INV', (int)$p->UserID);

    // Aset statis (opsional ganti sesuai lokasi file kamu)
    $logo_left  = base_url('assets/sb-admin2/img/hsilogo.png');           // logo HSI kiri
    $logo_right = base_url('assets/sb-admin2/img/hsilogo.png');                    // kalau punya logo LPK
    $stempel    = base_url('assets/sb-admin2/img/stamp_HSI.png');                   // nama file sesuai permintaan

    // Payload untuk view BARU (dan sekalian kompatibel view lama)
    $vars = [
        // nomor & tanggal
        'no_invoice'  => $no_inv,
        'invoice_no'  => $no_inv,
        'tanggal'     => date('Y-m-d'),

        // identitas penerima
        'nama'         => $p->NamaLengkap ?: $p->Username,
        'nama_lengkap' => $p->NamaLengkap ?: $p->Username, // kompatibilitas lama
        'email'        => $p->Email,
        'phone'        => $p->NoHP ?: $p->Phone,
        'siswaid'      => $p->SiswaID ?: '',
        'lpk'          => $p->NamaLPK ?: '-',

        // angka
        'sudah_bayar' => $sudah_bayar,
        'belum_bayar' => $belum_bayar,
        'total'       => $nominal,

        // item_rows masih dikirim untuk view lama (kalau masih dipakai di tempat lain)
        'item_rows' => [
            ['no'=>1, 'desc'=>'Biaya Pelatihan', 'amount'=>$nominal],
        ],
        'subtotal'  => $nominal,
        'ppn'       => 0,

        // aset visual untuk view baru
        'logo_left'   => $logo_left,
        'logo_right'  => $logo_right,
        'stempel_url' => $stempel,
        // 'ttd_url'   => base_url('assets/pdf/ttd_pimpinan.png'), // opsional
    ];

    // Render dan stream ke browser
    $html = $this->load->view('pdf/invoice_pelatihan', $vars, true);
    $this->_stream_pdf('INVOICE-'.$no_inv.'.pdf', $html);
}

// Endpoint print kwitansi (berdasarkan PembayaranID)

public function print_kwitansi($pembayaran_id)
{
    check_role([1,2]);

    $p = $this->db->select('
                p.*, u.Username, u.Email,
                COALESCE(s.NamaLengkap, u.Username) AS Nama,
                l.NamaLPK
            ')
        ->from('pembayaran p')
        ->join('users u','u.UserID = p.UserID','left')
        ->join('siswa s','s.SiswaID = p.SiswaID OR s.UserID = p.UserID','left')
        ->join('lpk l','l.LPKID = s.LPKID','left')
        ->where('p.PembayaranID', (int)$pembayaran_id)
        ->get()->row();

    if (!$p) show_error('Pembayaran tidak ditemukan.', 404);
    if (strtolower($p->StatusBayar) !== 'approved') {
        $this->session->set_flashdata('error','Kwitansi hanya untuk transaksi Approved.');
        return redirect('pembayaran_pelatihan/detail/'.($p->SiswaID ?: (int)$p->UserID));
    }

    $no_kw = doc_number('KW', (int)$pembayaran_id);
    $tanggal = !empty($p->TanggalBayar) ? date('Y-m-d', strtotime($p->TanggalBayar)) : date('Y-m-d');

    $html = $this->load->view('pdf/kwitansi_pelatihan', [
        'no_kwitansi' => $no_kw,
        'tanggal'     => $tanggal,
        'nama'        => $p->Nama ?? $p->Username,
        'lpk'         => $p->NamaLPK ?: '-',
        'keperluan'   => 'Biaya Pelatihan',
        'metode'      => $p->MetodeBayar ?? '-',
        'jumlah'      => (float)$p->JumlahBayar,
    ], true);

    $this->_stream_pdf('KWITANSI-'.$no_kw.'.pdf', $html);
}



    /* ==============================
     * UTIL
     * ============================== */

    /** Tentukan kolom tanggal yang aman (TanggalBayar/CreatedAt/PembayaranID) */
    private function _safe_order_col(string $table): string
    {
        $fields = array_map('strtolower', $this->db->list_fields($table));
        if (in_array('tanggalbayar', $fields, true)) return 'TanggalBayar';
        if (in_array('createdat', $fields, true))    return 'CreatedAt';
        return 'PembayaranID';
    }

    /** Hitung ulang total bayar & set status siswa aktif bila lunas */
    private function _recalculate_and_update_status($siswa_id)
    {
        if (empty($siswa_id)) return;

        $biaya       = $this->biaya->get_current(self::JENIS_KEY);
        $total_bayar = (float)$this->ledger->sum_nominal_by_siswa($siswa_id, self::JENIS_LABEL);

        if ($biaya && $total_bayar >= (float)$biaya->Nominal) {
            $this->siswa->update_status($siswa_id, self::STATUS_SISWA_AKTIF);
        }
    }

    /** Generate SiswaID baru: HSI00001, HSI00002, ... */
    private function _generate_siswa_id()
    {
        $row = $this->db->select('SiswaID')
                        ->like('SiswaID','HSI')
                        ->order_by('SiswaID','DESC')
                        ->limit(1)
                        ->get('Siswa')->row();

        $num = $row ? (int)substr($row->SiswaID, 3) + 1 : 1;
        return 'HSI'.str_pad($num, 5, '0', STR_PAD_LEFT);
    }

    /** Snapshot nama user: siswa.NamaLengkap → fallback users.Username */
    private function _current_user_snapshot(int $user_id): array
    {
        if (!$user_id) return ['nama' => ''];

        // pakai CreatedAt kalau ada; kalau tidak, jangan order_by
        $has_created = in_array('createdat', array_map('strtolower', $this->db->list_fields('siswa')), true);

        $this->db->select('s.NamaLengkap, u.Username')
                 ->from('siswa s')
                 ->join('users u', 'u.UserID = s.UserID', 'left')
                 ->where('s.UserID', $user_id)
                 ->limit(1);

        if ($has_created) $this->db->order_by('s.CreatedAt', 'DESC');

        $row = $this->db->get()->row();

        $nama = '';
        if ($row) {
            $nama = trim((string)$row->NamaLengkap);
            if ($nama === '') $nama = trim((string)$row->Username);
        }
        return ['nama' => $nama];
    }

// render PDF ke browser

    private function _stream_pdf(string $filename, string $html): void
{
    $this->load->library('Pdf_maker');
    $tmpDir = FCPATH.'uploads/tmp/';
    @mkdir($tmpDir, 0755, true);
    $path = $tmpDir.$filename;

    $this->pdf_maker->save_html_to_pdf($html, $path, 'A4', 'portrait');

    header('Content-Type: application/pdf');
    header('Content-Disposition: inline; filename="'.$filename.'"');
    header('Content-Length: '.filesize($path));
    readfile($path);
    @unlink($path);
    exit;
}


    /** Kirim invoice (PDF) setelah register – optional dipanggil manual */
    private function _send_invoice_after_register(int $user_id): bool
    {
        // Ambil user + siswa + nama LPK (jangan pakai s.AsalLPK)
        $row = $this->db->select('u.Email, u.Username, s.SiswaID, s.NamaLengkap, l.NamaLPK')
            ->from('users u')
            ->join('siswa s', 's.UserID = u.UserID', 'left')
            ->join('lpk l', 'l.LPKID = s.LPKID', 'left')
            ->where('u.UserID', $user_id)
            ->get()->row();

        if (!$row || empty($row->Email)) {
            log_message('error', 'Invoice: user/email tidak ditemukan untuk UserID='.$user_id);
            return false;
        }

        $biaya   = $this->biaya->get_current(self::JENIS_KEY);
        $nominal = $biaya ? (float)$biaya->Nominal : 0.0;

        // View PDF
        $no_inv = doc_number('INV', $user_id);
        $vars = [
            'no_invoice' => $no_inv,
            'tanggal'    => date('Y-m-d'),
            'nama'       => $row->NamaLengkap ?: $row->Username,
            'siswaid'    => $row->SiswaID ?: '',
            'lpk'        => $row->NamaLPK ?: '-',
            'email'      => $row->Email,
            'jumlah'     => $nominal,
        ];
        $html = $this->load->view('pdf/invoice_pelatihan', $vars, true);

        // Render PDF → file sementara
        $this->load->library('Pdf_maker');
        $tmpPath  = FCPATH.'uploads/tmp/';
        @mkdir($tmpPath, 0755, true);
        $filename = 'INVOICE-'.$no_inv.'.pdf';
        $pdfPath  = $tmpPath.$filename;

        try {
            $this->pdf_maker->save_html_to_pdf($html, $pdfPath, 'A4', 'portrait');
        } catch (Throwable $e) {
            log_message('error', 'Invoice PDF error: '.$e->getMessage());
            return false;
        }

        // Kirim email + attach by PATH
        $this->email->clear(true);
        $this->email->set_mailtype('html');
        $this->email->set_newline("\r\n");
        $this->email->set_crlf("\r\n");
        $this->email->from($this->config->item('smtp_user'), 'HSI Academy');
        $this->email->to($row->Email);
        $this->email->subject('Invoice Pendaftaran - HSI Academy');
        $this->email->message(
            'Halo <b>'.html_escape($vars['nama'])."</b>,<br><br>".
            'Terima kasih telah mendaftar. Invoice pendaftaran terlampir.<br>'.
            'No. Invoice: <b>'.$no_inv."</b><br><br>".
            'Salam,<br>HSI Academy'
        );
        $sent = $this->email->attach($pdfPath) && $this->email->send();
        @unlink($pdfPath);

        if (!$sent && method_exists($this->email, 'print_debugger')) {
            log_message('error', 'Email invoice gagal: '.$this->email->print_debugger(['headers']));
        }
        return (bool)$sent;
    }

    /** Kirim kwitansi (PDF) setelah approve */
    private function _send_kwitansi_after_approve(int $pembayaran_id): bool
    {
        // Ambil data penerima + context (NO s.AsalLPK)
        $p = $this->db->select('
                    p.*,
                    u.Email,
                    COALESCE(s.NamaLengkap, u.Username) AS Nama,
                    l.NamaLPK
                ')
            ->from('pembayaran p')
            ->join('users u','u.UserID = p.UserID','left')
            ->join('siswa s','s.SiswaID = p.SiswaID OR s.UserID = p.UserID','left')
            ->join('lpk l','l.LPKID = s.LPKID','left')
            ->where('p.PembayaranID', $pembayaran_id)
            ->get()->row();

        if (!$p || empty($p->Email)) {
            log_message('error', "KWITANSI: data email kosong / pembayaran_id={$pembayaran_id}");
            return false;
        }

        $no_kw = doc_number('KW', (int)$pembayaran_id);
        $tanggal = !empty($p->TanggalBayar) ? date('Y-m-d', strtotime($p->TanggalBayar)) : date('Y-m-d');

        $html = $this->load->view('pdf/kwitansi_pelatihan', [
            'no_kwitansi' => $no_kw,
            'tanggal'     => $tanggal,
            'nama'        => $p->Nama ?? '',
            'lpk'         => $p->NamaLPK ?? '-',
            'keperluan'   => 'Biaya Pelatihan',
            'metode'      => $p->MetodeBayar ?? '-',
            'jumlah'      => (float)$p->JumlahBayar,
        ], true);

        try {
            $this->load->library('Pdf_maker');
            $tmpDir   = FCPATH.'uploads/tmp/';
            @mkdir($tmpDir, 0755, true);

            $filename = 'Kwitansi-'.$no_kw.'.pdf';
            $fullpath = rtrim($tmpDir, '/').'/'.$filename;

            $this->pdf_maker->save_html_to_pdf($html, $fullpath, 'A4', 'portrait');
        } catch (Throwable $e) {
            log_message('error', 'KWITANSI_PDF_ERR: '.$e->getMessage());
            return false;
        }

        try {
            $this->email->clear(true);
            $this->email->from($this->config->item('smtp_user'), 'HSI Academy');
            $this->email->to($p->Email);
            $this->email->subject('Kwitansi Pembayaran - HSI');
            $this->email->message("Halo {$p->Nama},\n\nPembayaran Anda telah kami terima. Kwitansi terlampir.\n\nTerima kasih.");
            $this->email->attach($fullpath);
            $sent = $this->email->send();

            if (!$sent && method_exists($this->email, 'print_debugger')) {
                log_message('error', 'KWITANSI_EMAIL_ERR: '.$this->email->print_debugger(['headers']));
            }
            return (bool)$sent;
        } catch (Throwable $e) {
            log_message('error', 'KWITANSI_EMAIL_EX: '.$e->getMessage());
            return false;
        } finally {
            if (isset($fullpath) && is_file($fullpath)) {
                @unlink($fullpath);
            }
        }
    }
}
