<?php
namespace App\Controllers\Admin;

use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

use App\Controllers\BaseController;
use CodeIgniter\API\ResponseTrait;
use App\Models\Jeniskkmodel;
use App\Models\Gruppembayaranmodel;
use App\Models\Iuranmodel;
use App\Models\Invoicemodel;
use App\Models\Kkmodel;
use App\Models\Strukmodel;
use App\Models\Tarifmodel;
use App\Models\Diskonmodel;

use Dompdf\Dompdf;
use Dompdf\Options;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Label\Label;
use Endroid\QrCode\Logo\Logo;
use Endroid\QrCode\RoundBlockSizeMode;
use Endroid\QrCode\Writer\PngWriter;
use Endroid\QrCode\Writer\ValidationException;

class Invoice extends BaseController
{
    use ResponseTrait;

    private $user;

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger) 
    {
        parent::initController($request, $response, $logger);
        $this->user = service("user_data");
    }

    private function check_access(){
        $user = service("user_data");
        if($user->data->group != 'admin'){
            return false;
        }else{
            return true;
        }
    }

    public function index(){
        $data['user'] = $this->user->data;
        return view('admin/invoice/index',$data);
    }

    public function open(){
        $data['user'] = $this->user->data;

        $db = db_connect();
        $data['total_kk'] = $db->table("kk")->countAll();
        $data['total_open_invoice'] = $db->table("invoice")->where("flag_close","0")->countAllResults();

        return view('admin/invoiceopen/index',$data);
    }

    public function ajax_dt_open(){
        $data_post = [
            'draw' => $this->request->getPost('draw'),
            'columns' => $this->request->getPost('columns'),
            'order' => $this->request->getPost('order'),
            'start' => $this->request->getPost('start'),
            'length' => $this->request->getPost('length'),
            'search' => $this->request->getPost('search'),
            'searchBuilder' => $this->request->getPost('searchBuilder'),
        ];
        $DataModel = new Invoicemodel();
        return $DataModel->GetDTOpen($data_post,"");
    }

    public function generate_invoice()
    {
        $data['user'] = $this->user->data;

        $db = db_connect();
        $data['total_kk'] = $db->table("kk")->countAll();
        $data['total_open_invoice'] = $db->table("invoice")->where("flag_close","0")->countAllResults();

        return view('admin/invoiceopen/generate_invoice',$data);
    }

    public function proses_generate() {
        $startDate = $this->request->getPost('start_date');
        $endDate = $this->request->getPost('end_date');
        $page = $this->request->getPost('page');
        $limit = $this->request->getPost('limit');
        $id_grup_transaksi = $this->request->getPost('id_grup_transaksi');

        $offset = ($page - 1) * $limit;

        $kkmodel = new Kkmodel();
        $wargaList = $kkmodel->orderBy('id_kk')->findAll($limit, $offset);

        $invoicemodel = new Invoicemodel();

        foreach ($wargaList as $warga) {
            $id_kk = $warga['id_kk'];
            // Loop semua tanggal antara start dan end (bisa bulanan atau harian tergantung logikamu)
            $current = strtotime($startDate);
            $end = strtotime($endDate);

            while ($current <= $end) {
                $month = date('m', $current);
                $year = date('Y', $current);

                $existing = $invoicemodel
                    ->where('id_kk', $warga['id_kk'])
                    ->where('bulan', $month)
                    ->where('tahun', $year)
                    ->first();

                $tarif = 0;
                $id_tarif = "";

                $diskon = 0;
                $id_diskon = 0;

                $tarifmodel = new Tarifmodel();
                $db_tarif = $tarifmodel->db;
                $cek_date = $year."-".str_pad($month,2,"0",STR_PAD_LEFT)."-01";
                $query_tarif = $db_tarif->query("select * from tarif where id_kk='".$id_kk."' and start_date <='".$cek_date."' and (end_date >= '".$cek_date."' or end_date='9999-12-31') and deleted_at is null order by end_date desc");

                $tarif_row = $query_tarif->getRow();

                if($tarif_row != null){
                    $id_tarif = $tarif_row->id_tarif;
                    $tarif = $tarif_row->nominal;
                }

                $diskonmodel = new Diskonmodel();
                $db_diskon = $diskonmodel->db;
                $cek_date = $year."-".str_pad($month,2,"0",STR_PAD_LEFT)."-01";
                $query_diskon = $db_diskon->query("select * from diskon where id_kk='".$id_kk."' and start_date <='".$cek_date."' and (end_date >= '".$cek_date."' or end_date='9999-12-31') and deleted_at is null order by end_date desc");

                $diskon_row = $query_diskon->getRow();

                if($diskon_row != null){
                    $id_diskon = $diskon_row->id_diskon;
                    $diskon = $diskon_row->nominal;
                }

                if (!$existing) {
                    if(!empty($id_tarif)){
                        //pastikan tarif ada
                        $cek_date = $year.str_pad($month,2,"0",STR_PAD_LEFT);
                        $nomor_invoice = $invoicemodel->getNewKode($cek_date);
                        if (empty($nomor_invoice)){
                            return $this->response->setJSON([
                                'success' => false,
                                'hasNext' => false
                            ]);
                        }

                        $input_invoice = [
                            "id_grup_transaksi" => $id_grup_transaksi,
                            "id_tarif" => $id_tarif,
                            "id_diskon" => $id_diskon,
                            "id_kk" => $id_kk,
                            "nomor" => $nomor_invoice,
                            "bulan" => $month,
                            "tahun" => $year,
                            "nominal" => $tarif,
                            "nominal_diskon" => $diskon,
                            "nominal_akhir" => ($tarif - $diskon),
                            "created_by" => $this->user->data->id_auth,
                            "updated_by" => $this->user->data->id_auth
                        ];

                        $id_invoice = $invoicemodel->insert($input_invoice);
                    }
                }else{
                    if($existing['flag_close'] == '0'){
                        if(($existing['nominal'] != $tarif) || ($existing['nominal_diskon'] != $diskon)){
                            //update tarif invoice dengan yg terbaru
                            $update = [
                                "id_tarif" => $id_tarif,
                                "id_diskon" => $id_diskon,
                                "nominal" => $tarif,
                                "nominal_diskon" => $diskon,
                                "nominal_akhir" => ($tarif - $diskon)
                            ];
                            $invoicemodel->update($existing->id_invoice,$update);
                        }
                    }
                }

                $current = strtotime('+1 month', $current);
            }
        }

        $totalWarga = $kkmodel->db->table("kk")->countAll();
        $hasNext = ($offset + $limit) < $totalWarga;

        return $this->response->setJSON([
            'success' => true,
            'hasNext' => $hasNext
        ]);
    }

    public function cetak_invoice($id_invoice){
        $user = $this->user->data;
        $data = array();
        $data["company_name"] = COMPANY_NAME;
        $data["company_logo"] = base_url("img/logo_company.png");

        $invoicemodel = new Invoicemodel();
        $invoicemodel = $invoicemodel->builder("vinvoice");
        $invoicemodel->where("id_invoice",$id_invoice);
        $invoice = $invoicemodel->get()->getRow();

        if(is_null($invoice)){
            die("Invoice not available");
        }

        if($invoice->flag_close=='1'){
            $invoicemodel = new Invoicemodel();
            $invoicemodel = $invoicemodel->builder("vinvoiceclosed");
            $invoicemodel->where("id_invoice",$id_invoice);
            $invoice = $invoicemodel->get()->getRow();

            if(is_null($invoice)){
                die("Invoice not available");
            }
        }
        $data["tanggal"] = date("d M Y");
        if(isset($invoice->kode_transaksi)){
            $data["nomor_transaksi"] = $invoice->kode_transaksi;
        }
        $data["nomor_invoice"] = $invoice->nomor_invoice;
        $data['kode_rumah'] = $invoice->kode;
        $data['nama_pemilik'] = $invoice->nama_pemilik;
        $data['alamat'] = $invoice->jalan.', '.$invoice->blok.', No. '.$invoice->nomor_rumah;
        $data['nominal'] = $invoice->nominal_akhir;
        $data['status'] = $invoice->flag_close;
        $data['receiver'] = $invoice->nama_pemilik;
        $data['operator'] = $user->nama;

        // ===== Data Transaksi ===== //
        $qr_text = base_url().'vwarga/cetak_invoice/'.$invoice->id_invoice;

        // ===== Buat QR Code ===== //
        $writer = new PngWriter();
        $qrCode = new QrCode(
            data: $qr_text,
            encoding: new Encoding('UTF-8'),
            errorCorrectionLevel: ErrorCorrectionLevel::Low,
            size: 100,
            margin: 0,
            roundBlockSizeMode: RoundBlockSizeMode::Margin,
            foregroundColor: new Color(0, 0, 0),
            backgroundColor: new Color(255, 255, 255)
        );

        $result = $writer->write($qrCode);

        ob_start();
        $result->saveToFile('php://output');
        $imageData = ob_get_clean();
        $base64 = base64_encode($imageData);
        $imgSrc = 'data:image/png;base64,' . $base64;
        
        $data['qr_code'] = $imgSrc;
        $data["periode"] = $invoice->periode;

        $html = view('print/invoice', $data);

        while (ob_get_level()) {
            ob_end_clean();
        }
        
        $options = new Options();
        $options->set('isRemoteEnabled', true);
        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);
        $dompdf->setPaper([0, 0, 93.2, 241.3], 'portrait'); // 1/3 folio
        $dompdf->render();
        $dompdf->stream('invoice.pdf', ['Attachment' => false]);
    }

    public function cetak_invoice_open()
    {
        $data['user'] = $this->user->data;

        $db = db_connect();
        $data['total_kk'] = $db->table("kk")->countAll();
        $data['total_open_invoice'] = $db->table("invoice")->where("flag_close","0")->countAllResults();

        return view('admin/invoiceopen/cetak_invoice_open',$data);
    }

    public function proses_cetak_invoice_open(){
        $user = $this->user->data;
        $id_kk = $this->request->getPost('id_kk');
        $startDate = $this->request->getPost('start_date');
        $endDate = $this->request->getPost('end_date');

        $current = strtotime($startDate);
        $end = strtotime($endDate);

        $data = array();
        $data["company_name"] = COMPANY_NAME;
        $data["company_logo"] = base_url("img/logo_company.png");
        $data['invoices'] = array();

        $i=0;
        while ($current <= $end) {
            $month = date('m', $current);
            $year = date('Y', $current);
            $invoicemodel = new Invoicemodel();
            $invoicemodel = $invoicemodel->builder("vinvoiceopen");
            $invoicemodel->where("bulan",$month);
            $invoicemodel->where("tahun",$year);
            if(!empty($id_kk)){
                $invoicemodel->where("id_kk",$id_kk);
            }

            $invoice = $invoicemodel->get()->getRow();
            if($invoice != null){
                $data['invoices'][$i]["tanggal"] = date("d M Y");
                $data['invoices'][$i]["nomor_invoice"] = $invoice->nomor_invoice;
                $data['invoices'][$i]['kode_rumah'] = $invoice->kode;
                $data['invoices'][$i]['nama_pemilik'] = $invoice->nama_pemilik;
                $data['invoices'][$i]['alamat'] = $invoice->jalan.', '.$invoice->invoice.', No. '.$invoice->nomor_rumah;
                $data['invoices'][$i]['nominal'] = $invoice->nominal_akhir;
                $data['invoices'][$i]['status'] = $invoice->flag_close;
                $data['invoices'][$i]['receiver'] = $invoice->nama_pemilik;
                $data['invoices'][$i]['operator'] = $user->nama;

                // ===== Data Transaksi ===== //
                $qr_text = base_url().'vwarga/cetak_invoice/'.$invoice->id_invoice;

                // ===== Buat QR Code ===== //
                $writer = new PngWriter();
                $qrCode = new QrCode(
                    data: $qr_text,
                    encoding: new Encoding('UTF-8'),
                    errorCorrectionLevel: ErrorCorrectionLevel::Low,
                    size: 100,
                    margin: 0,
                    roundBlockSizeMode: RoundBlockSizeMode::Margin,
                    foregroundColor: new Color(0, 0, 0),
                    backgroundColor: new Color(255, 255, 255)
                );

                $result = $writer->write($qrCode);

                ob_start();
                $result->saveToFile('php://output');
                $imageData = ob_get_clean();
                $base64 = base64_encode($imageData);
                $imgSrc = 'data:image/png;base64,' . $base64;
                
                $data['invoices'][$i]['qr_code'] = $imgSrc;
                $data['invoices'][$i]["periode"] = $invoice->periode;

                $i++;
            }

            $current = strtotime('+1 month', $current);
        }

        $html = view('print/multiple_invoice', $data);
        while (ob_get_level()) {
            ob_end_clean();
        }

        $options = new Options();
        $options->set('isRemoteEnabled', true);
        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);
        $dompdf->setPaper([0, 0, 93.2, 241.3], 'portrait'); // 1/3 folio
        $dompdf->render();
        $dompdf->stream('invoice.pdf', ['Attachment' => false]);
    }

    public function closed(){
        $data['user'] = $this->user->data;

        $db = db_connect();
        $data['total_kk'] = $db->table("kk")->countAll();
        $data['total_closed_invoice'] = $db->table("vinvoiceclosed")->countAll();

        return view('admin/invoiceclose/index',$data);
    }

    public function ajax_dt_closed(){
        $data_post = [
            'draw' => $this->request->getPost('draw'),
            'columns' => $this->request->getPost('columns'),
            'order' => $this->request->getPost('order'),
            'start' => $this->request->getPost('start'),
            'length' => $this->request->getPost('length'),
            'search' => $this->request->getPost('search'),
            'searchBuilder' => $this->request->getPost('searchBuilder'),
        ];
        $DataModel = new Invoicemodel();
        return $DataModel->GetDTClose($data_post,"");
    }

    public function cetak_invoice_closed()
    {
        $data['user'] = $this->user->data;

        $db = db_connect();
        $data['total_kk'] = $db->table("kk")->countAll();
        $data['total_closed_invoice'] = $db->table("vinvoiceclosed")->countAll();

        return view('admin/invoiceclose/cetak_invoice_closed',$data);
    }

    public function proses_cetak_invoice_closed(){
        $user = $this->user->data;
        $id_kk = $this->request->getPost('id_kk');
        $startDate = $this->request->getPost('start_date');
        $endDate = $this->request->getPost('end_date');

        $current = strtotime($startDate);
        $end = strtotime($endDate);

        $data = array();
        $data["company_name"] = COMPANY_NAME;
        $data["company_logo"] = base_url("img/logo_company.png");
        $data['invoices'] = array();

        $i=0;
        while ($current <= $end) {
            $month = date('n', $current);
            $year = date('Y', $current);
            $invoicemodel = new Invoicemodel();
            $invoicemodel = $invoicemodel->builder("vinvoiceclosed");
            $invoicemodel->where("bulan",$month);
            $invoicemodel->where("tahun",$year);
            if(!empty($id_kk)){
                $invoicemodel->where("id_kk",$id_kk);
            }

            $invoice = $invoicemodel->get()->getRow();
            if($invoice != null){
                $data['invoices'][$i]["tanggal"] = date("d M Y");
                $data['invoices'][$i]["nomor_invoice"] = $invoice->nomor_invoice;
                $data['invoices'][$i]["nomor_transaksi"] = $invoice->kode_transaksi;
                $data['invoices'][$i]['kode_rumah'] = $invoice->kode;
                $data['invoices'][$i]['nama_pemilik'] = $invoice->nama_pemilik;
                $data['invoices'][$i]['alamat'] = $invoice->jalan.', '.$invoice->blok.', No. '.$invoice->nomor_rumah;
                $data['invoices'][$i]['nominal'] = $invoice->nominal_akhir;
                $data['invoices'][$i]['status'] = $invoice->flag_close;
                $data['invoices'][$i]['receiver'] = $invoice->nama_pemilik;
                $data['invoices'][$i]['operator'] = $user->nama;

                // ===== Data Transaksi ===== //
                $qr_text = base_url().'vwarga/cetak_invoice/'.$invoice->id_invoice;

                // ===== Buat QR Code ===== //
                $writer = new PngWriter();
                $qrCode = new QrCode(
                    data: $qr_text,
                    encoding: new Encoding('UTF-8'),
                    errorCorrectionLevel: ErrorCorrectionLevel::Low,
                    size: 100,
                    margin: 0,
                    roundBlockSizeMode: RoundBlockSizeMode::Margin,
                    foregroundColor: new Color(0, 0, 0),
                    backgroundColor: new Color(255, 255, 255)
                );

                $result = $writer->write($qrCode);

                ob_start();
                $result->saveToFile('php://output');
                $imageData = ob_get_clean();
                $base64 = base64_encode($imageData);
                $imgSrc = 'data:image/png;base64,' . $base64;
                
                $data['invoices'][$i]['qr_code'] = $imgSrc;
                $data['invoices'][$i]["periode"] = $invoice->periode;

                $i++;
            }

            $current = strtotime('+1 month', $current);
        }

        $html = view('print/multiple_invoice', $data);
        while (ob_get_level()) {
            ob_end_clean();
        }
        $options = new Options();
        $options->set('isRemoteEnabled', true);
        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);
        $dompdf->setPaper([0, 0, 93.2, 241.3], 'portrait'); // 1/3 folio
        $dompdf->render();
        $dompdf->stream('invoice.pdf', ['Attachment' => false]);
    }

    public function view_closed($id) {
        $data['user'] = $this->user->data;
        $invmodel = new Invoicemodel();
        
        $builder = $invmodel->builder("vinvoiceclose");
        $data['data'] = $builder->where("id_invoice",$id)->get()->getRow();
        
        if($data['data'] == null){
            return redirect()->to('invoice/open');
        }
        return view('admin/invoiceclose/view',$data);
    }

    public function cetak_struk($id) {
        $data['user'] = $this->user->data;
        $invmodel = new Invoicemodel();
        
        $builder = $invmodel->builder("vinvoiceclose");
        $data_invoice = $builder->where("id_invoice",$id)->get()->getRow();
        
        if($data_invoice == null){
            die("-");
        }
        
        // ===== Data Transaksi ===== //
        $invoice_number = $data_invoice->nomor;
        $struk_number = $data_invoice->nomor_struk;
        $jenis_pembayaran = $data_invoice->nama_grup_pembayaran;
        $date = date("Y-m-d H:i:s");
        $total = $data_invoice->biaya;
        $qr_text = base_url().'cek_struk/'.$invoice_number;

        // ===== Buat QR Code ===== //
        $writer = new PngWriter();
        $qrCode = new QrCode(
            data: $qr_text,
            encoding: new Encoding('UTF-8'),
            errorCorrectionLevel: ErrorCorrectionLevel::Low,
            size: 100,
            margin: 10,
            roundBlockSizeMode: RoundBlockSizeMode::Margin,
            foregroundColor: new Color(0, 0, 0),
            backgroundColor: new Color(255, 255, 255)
        );

        $result = $writer->write($qrCode);

        ob_start();
        $result->saveToFile('php://output');
        $imageData = ob_get_clean();
        $base64 = base64_encode($imageData);
        $imgSrc = 'data:image/png;base64,' . $base64;

        // ===== HTML STRUK (Thermal 58mm Style) ===== //
        $html = '
        <html>
        <head>
        <style>
            @page { size: 58mm auto; margin: 0; }
            body { font-family: monospace; font-size: 10px; margin: 10px; padding:5px; border:1px dotted; }
            .center { text-align: center; }
            .bold { font-weight: bold; }
            table { width: 100%; border-collapse: collapse; }
            td { padding: 2px 0; }
            .qr { margin-top: 10px; }
        </style>
        </head>
        <body>
        <div class="center bold">KWITANSI '.$jenis_pembayaran.'</div>
        <div class="center bold">TAHUN '.date("Y").'</div>
        <div class="center">Pengelola Perumahan Cemara Asri</div>
        <hr>
        <div>No Invoice: <b>' . $invoice_number . '</b></div>
        <div>No Struk: <b>' . $struk_number . '</b></div>
        <div>Tanggal: ' . $date . '</div>
        <hr>
        <table>
            <tr><td>Nama Pemilik</td><td>:</td><td>'.$data_invoice->nama_pemilik.'</td></tr>
            
            <tr><td>Alamat</td><td>:</td><td>'.$data_invoice->nama_jalan.' '.$data_invoice->nama_blok.' '.$data_invoice->nomor_rumah.'</td></tr>
            <tr><td>Periode</td><td>:</td><td>'.$data_invoice->bulan.' - '.$data_invoice->tahun.'</td></tr>
            <tr><td>Nominal</td><td>:</td><td>Rp '.number_format($data_invoice->biaya,0,".",",").'</td></tr>
            <tr><td colspan="3"><hr></td></tr>
            <tr><td>Diterima Oleh</td><td>:</td><td>'.$data_invoice->pembayar.'</td></tr>
            <tr><td>Operator</td><td>:</td><td>'.$data_invoice->nama_operator.'</td></tr>
        </table>
        <div class="center qr">
            <img src="' . $imgSrc . '" width="100">
            <div>Scan untuk verifikasi</div>
        </div>
        <div class="center">Perhatian</div>
        <div class="center">Jangan menerima Petugas Collector tanpa Tanda Pengenal. Kwitansi SAH & ASLI jika dibubuhi dengan stempel Pengelola Perumahan Cemara Asri</div>
        </body>
        </html>
        ';

        // ===== Generate PDF ===== //
        //die(var_dump($html));
        $dompdf = new Dompdf();
        $dompdf->loadHtml($html);
        $dompdf->setPaper([0, 0, 164, 400], 'portrait'); // 58mm = ~164pt
        $dompdf->render();
        $dompdf->stream("struk-$invoice_number.pdf", ["Attachment" => false]);

        // Optional: hapus QR sementara
        //unlink($qrPath);
    }
}
?>