<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use App\Models\CustomerModel;
use App\Models\DetailKainModel;
use App\Models\DetailPermintaanModel;
use App\Models\JenisKainModel;
use App\Models\ModelCustomModel;
use App\Models\PermintaanCustomModel;
use App\Models\RiwayatPerubahanModel;
use Dompdf\Dompdf;
use Dompdf\Options;
use CodeIgniter\HTTP\ResponseInterface;

class TransactionController extends BaseController
{
    protected $permintaanCustom;
    protected $modelCustom;
    protected $detailKain;
    protected $detailPermintaan;
    protected $customer;
    protected $riwayatPerubahanModel;
    protected $jenisKain;

    public function __construct()
    {
        $this->permintaanCustom = new PermintaanCustomModel();
        $this->customer = new CustomerModel();
        $this->jenisKain = new JenisKainModel();
        $this->modelCustom = new ModelCustomModel();
        $this->riwayatPerubahanModel = new RiwayatPerubahanModel();
        $this->detailKain = new DetailKainModel();
        $this->detailPermintaan = new DetailPermintaanModel();
    }

    protected function formatDatetimeInput($input)
    {
        if (!$input) return null;
        $normalized = str_replace('T', ' ', $input);
        if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $normalized)) {
            $normalized .= ':00';
        }
        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $normalized)) {
            $normalized .= ' 00:00:00';
        }
        $ts = strtotime($normalized);
        if ($ts === false) return null;
        return date('Y-m-d H:i:s', $ts);
    }

    public function index()
    {
        $data['title'] = 'Transaksi';
        $builder = $this->permintaanCustom->builder();
        $builder->select('tabel_permintaan_custom.*,tabel_customer.nama');
        $builder->join('tabel_customer', 'tabel_customer.id_customer = tabel_permintaan_custom.id_customer', 'inner');
        if (auth()->user()->role == 'customer'):
            $builder->where('tabel_permintaan_custom.id_customer', auth()->user()->user_id);
        endif;

        $data['data'] = $builder->orderBy('tabel_permintaan_custom.created_at', 'desc')->get()->getResult();

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

    public function pay_proccess($id)
    {
        $request = $this->request;
        $PermintaanCustom = $this->permintaanCustom->find($id);

        if (!$PermintaanCustom) {
            return redirect()->back()->with('error', 'Pesanan tidak ditemukan');
        }

        $tanggal_pelunasan = $this->request->getPost('tanggal_pelunasan');
        $jumlah_bayar = $this->request->getPost('jumlah_bayar');
        $metode_pembayaran = $this->request->getPost('metode_pembayaran') ?? 'transfer';

        // Customer dan kasir bisa process payment
        $role = auth()->user()->role;
        if ($role != 'kasir' && $role != 'customer' && $role != 'admin') {
            return redirect()->back()->with('error', 'Anda tidak memiliki akses untuk memproses pembayaran');
        }

        // Cek apakah ini pembayaran pertama atau pelunasan
        $sudahBayarDP = ($PermintaanCustom->status_pelunasan == 1);
        $dpSebelumnya = $PermintaanCustom->dp_pembayaran ?? 0;
        $sisaPembayaran = $PermintaanCustom->sisa_pembayaran ?? $PermintaanCustom->nominal_pelunasan;

        // Handle upload bukti transfer (khusus customer)
        $buktiTransfer = null;
        if ($role == 'customer' && $request->getFile('bukti_transfer')) {
            $file = $request->getFile('bukti_transfer');
            if ($file->isValid() && !$file->hasMoved()) {
                $destinationPath = FCPATH . 'assets/proof_of_payment/';

                // Create directory if not exists
                if (!is_dir($destinationPath)) {
                    mkdir($destinationPath, 0755, true);
                }

                $newFileName = time() . '_' . uniqid() . '.' . $file->getClientExtension();
                $file->move($destinationPath, $newFileName);
                $buktiTransfer = 'assets/proof_of_payment/' . $newFileName;
            }
        }

        // Validation untuk pembayaran pertama (DP)
        if (!$sudahBayarDP) {
            if ($jumlah_bayar <= 0) {
                return redirect()->back()->with('warning', 'Jumlah pembayaran harus lebih dari 0');
            }
            if ($jumlah_bayar > $PermintaanCustom->nominal_pelunasan) {
                return redirect()->back()->with('warning', 'Jumlah pembayaran tidak boleh melebihi total pesanan');
            }

            // Hitung sisa pembayaran
            $sisa = $PermintaanCustom->nominal_pelunasan - $jumlah_bayar;
            $status_pelunasan = ($sisa == 0) ? 2 : 1; // 1=DP, 2=Lunas
            $status_pesanan = 'menunggu_konfirmasi';

            $data = [
                'tanggal_pelunasan' => $tanggal_pelunasan,
                'dp_pembayaran' => $jumlah_bayar,
                'status_pelunasan' => $status_pelunasan,
                'sisa_pembayaran' => $sisa,
                'metode_pembayaran' => $metode_pembayaran,
                'status_pesanan' => $status_pesanan,
            ];

            // Tambahkan bukti transfer jika ada (customer)
            if ($buktiTransfer) {
                // Jika lunas langsung, simpan ke bukti_pembayaran (pelunasan)
                // Jika DP, simpan ke bukti_pembayaran_dp
                if ($status_pelunasan == 2) {
                    $data['bukti_pembayaran'] = $buktiTransfer;
                } else {
                    $data['bukti_pembayaran_dp'] = $buktiTransfer;
                }
            }

            $message = ($status_pelunasan == 2) ? 'Pembayaran lunas berhasil dicatat' : 'Pembayaran DP berhasil dicatat. Sisa: Rp ' . number_format($sisa, 0, ",", ".");
        }
        // Validation untuk pelunasan (sudah bayar DP)
        else {
            // Harus TEPAT sama dengan sisa pembayaran
            if ($jumlah_bayar != $sisaPembayaran) {
                return redirect()->back()->with('warning', 'Pembayaran pelunasan harus TEPAT sebesar sisa pembayaran: Rp ' . number_format($sisaPembayaran, 0, ",", "."));
            }

            $status_pesanan = 'menunggu_konfirmasi';

            $data = [
                'tanggal_pelunasan' => $tanggal_pelunasan,
                'status_pelunasan' => 2, // Lunas
                'sisa_pembayaran' => 0,
                'status_pesanan' => $status_pesanan,
                'metode_pembayaran' => $metode_pembayaran,
            ];

            // Tambahkan bukti transfer pelunasan jika ada (customer)
            if ($buktiTransfer) {
                $data['bukti_pembayaran'] = $buktiTransfer;
            }

            $message = 'Pembayaran pelunasan berhasil dicatat. Pesanan telah lunas!';
        }

        $this->permintaanCustom->update($id, $data);

        // LOCK ALAMAT setelah pembayaran pertama (DP atau Lunas)
        if (!$sudahBayarDP) {
            $this->permintaanCustom->lockAlamat($id);

            // Update status pesanan based on payment status
            // Jika lunas langsung, status -> diproses
            // Jika DP saja, status -> menunggu_input_meter
            $statusPesanan = ($status_pelunasan == 2) ? 'diproses' : 'menunggu_konfirmasi';
            $this->permintaanCustom->update($id, [
                'status_pesanan' => $statusPesanan,
                'payment_completed_at' => date('Y-m-d H:i:s')
            ]);
        }
        // Jika pelunasan setelah DP, update status menjadi diproses
        else {
            $this->permintaanCustom->update($id, [
                'status_pesanan' => 'diproses',
                'payment_completed_at' => date('Y-m-d H:i:s')
            ]);
        }

        session()->setFlashdata('success', $message);

        // Redirect sesuai role
        if ($role == 'customer') {
            return redirect()->to('/permintaan_custom');
        } else {
            return redirect()->to('/permintaan_custom');
        }
    }


    public function pay_dp($id)
    {
        if ($this->request->getMethod() == 'POST') {
            $request = $this->request;
            $PermintaanCustom = $this->permintaanCustom->find($id);

            $status = $this->request->getPost('status');
            $tanggal_pelunasan = $this->request->getPost('tanggal_pelunasan');
            $jumlah_bayar = $this->request->getPost('jumlah_bayar');

            if ($status == 2 && $jumlah_bayar < $PermintaanCustom->sisa_pembayaran) {
                return redirect()->to('transactions')->with('warning',  'Nominal pembayaran kurang, silahkan cek kembali');
            }

            // Validasi: Cek apakah semua meter pemakaian sudah diisi (> 0)
            // Skip validation for items with bawa_kain_sendiri
            $detailKain = new \App\Models\DetailKainModel();
            $detailPermintaan = new \App\Models\DetailPermintaanModel();

            $builder = $detailPermintaan->builder();
            $builder->select('tabel_detail_permintaan.bawa_kain_sendiri, tabel_detail_kain.meter_pemakaian, tabel_detail_kain.id_detail_kain');
            $builder->join('tabel_detail_kain', 'tabel_detail_kain.id_detail_order = tabel_detail_permintaan.id_detail_order', 'left');
            $builder->where('tabel_detail_permintaan.no_order_custom', $PermintaanCustom->no_order_custom);
            $detailItems = $builder->get()->getResult();

            $hasMissingMeter = false;
            foreach ($detailItems as $item) {
                // Skip validation if customer brings their own fabric
                if (isset($item->bawa_kain_sendiri) && $item->bawa_kain_sendiri == 1) {
                    continue;
                }
                // Check if meter is missing or zero for regular items
                if (empty($item->meter_pemakaian) || $item->meter_pemakaian == 0) {
                    $hasMissingMeter = true;
                    break;
                }
            }

            if ($hasMissingMeter) {
                session()->setFlashdata('error', 'Tidak dapat melakukan pembayaran. Meter pemakaian kain belum diinputkan. Silakan hubungi kasir untuk menginputkan meter pemakaian terlebih dahulu.');
                return redirect()->to('/permintaan_custom');
            }


            $image = null;
            if ($request->getFile('bukti_pembayaran') && $request->getFile('bukti_pembayaran')->isValid()) {
                $file = $request->getFile('bukti_pembayaran');
                $destinationPath = FCPATH . 'assets/proof_of_payment/';
                $newFileName = rand() . '.' . $file->getClientExtension();
                $file->move($destinationPath, $newFileName);
                $image = 'assets/proof_of_payment/' . $newFileName;
            }

            $data = [
                'tanggal_pelunasan' => $tanggal_pelunasan,
                'status_pelunasan' => $status,
                'dp_pembayaran' => $status == 1 ? ($PermintaanCustom->dp_pembayaran + $jumlah_bayar) : 0,
                'sisa_pembayaran' => $status == 1 ? $PermintaanCustom->nominal_pelunasan - ($PermintaanCustom->dp_pembayaran + $jumlah_bayar) : 0,
                'bukti_pembayaran' => $image,
            ];

            $this->permintaanCustom->update($id, $data);

            session()->setFlashdata('success', 'Pembayaran Berhasil');
            return redirect()->to('/permintaan_custom');
        }
        $data['title'] = 'Bayar Model';
        $builder = $this->permintaanCustom->builder();
        $builder->select('tabel_permintaan_custom.*,tabel_customer.nama');
        $builder->join('tabel_customer', 'tabel_customer.id_customer = tabel_permintaan_custom.id_customer', 'inner');
        $builder->where('tabel_permintaan_custom.kode_permintaan_custom', $id);
        $permintaanCustom = $builder->orderBy('tabel_permintaan_custom.created_at', 'desc')->get()->getRow();

        if (!$permintaanCustom) {
            return redirect()->to('/permintaan_custom')->with('error', 'Order tidak ditemukan');
        }
        $permintaanCustom->total_order = $this->detailPermintaan->selectSum('jumlah_pcs')->where('no_order_custom', $permintaanCustom->no_order_custom)->get()->getRow()->jumlah_pcs ?? 0;
        $data['data'] = $permintaanCustom;

        // Use LEFT JOIN to include items with bawa_kain_sendiri or upload_model_sendiri (NULL values)
        $builder = $this->detailPermintaan->builder();
        $builder->select('tabel_detail_permintaan.*, tabel_detail_kain.meter_pemakaian, tabel_detail_kain.harga_per_meter, tabel_detail_kain.subtotal_detail_kain, tabel_detail_kain.kode_jenis_kain, tabel_detail_kain.additional_fabrics, tabel_jenis_kain.nama_jenis_kain, tabel_jenis_kain.warna, tabel_jenis_kain.foto_jenis_kain, tabel_model.nama_model, tabel_model.foto_model');
        $builder->join('tabel_detail_kain', 'tabel_detail_kain.id_detail_order = tabel_detail_permintaan.id_detail_order', 'left');
        $builder->join('tabel_jenis_kain', 'tabel_jenis_kain.kode_jenis_kain = tabel_detail_kain.kode_jenis_kain', 'left');
        $builder->join('tabel_model', 'tabel_model.kode_model = tabel_detail_permintaan.kode_model', 'left');
        $builder->where('tabel_detail_permintaan.no_order_custom', $permintaanCustom->no_order_custom);
        $detailResult = $builder->orderBy('tabel_detail_permintaan.created_at', 'desc')->get()->getResult();

        // Debug log
        log_message('debug', 'TransactionController pay_dp - Detail Model Count: ' . count($detailResult));
        log_message('debug', 'TransactionController pay_dp - Order: ' . $permintaanCustom->no_order_custom);

        $data['detail_model'] = $detailResult;
        $data['riwayatPerubahanModel'] = $this->riwayatPerubahanModel;

        return view('permintaan_custom/pay', $data);
    }

    public function invoice($id)
    {

        $builder = $this->permintaanCustom->builder();
        $builder = $this->permintaanCustom->builder();
        $builder->select('tabel_permintaan_custom.*,tabel_customer.*');
        $builder->join('tabel_customer', 'tabel_customer.id_customer = tabel_permintaan_custom.id_customer', 'inner');
        $builder->where('tabel_permintaan_custom.kode_permintaan_custom', $id);
        $permintaanCustom = $builder->orderBy('tabel_permintaan_custom.created_at', 'desc')->get()->getRow();

        $builder = $this->detailPermintaan->builder();
        $builder->select('tabel_detail_permintaan.*,tabel_detail_kain.*,tabel_jenis_kain.nama_jenis_kain,tabel_jenis_kain.warna,tabel_jenis_kain.foto_jenis_kain,tabel_model.nama_model,tabel_model.foto_model');
        $builder->join('tabel_detail_kain', 'tabel_detail_kain.id_detail_order = tabel_detail_permintaan.id_detail_order', 'inner');
        $builder->join('tabel_jenis_kain', 'tabel_jenis_kain.kode_jenis_kain = tabel_detail_kain.kode_jenis_kain', 'inner');
        $builder->join('tabel_model', 'tabel_model.kode_model = tabel_detail_permintaan.kode_model', 'inner');
        $builder->where('tabel_detail_permintaan.no_order_custom', $permintaanCustom->no_order_custom);
        $items = $builder->orderBy('tabel_detail_permintaan.created_at', 'desc')->get()->getResult();

        // 🔹 kirim data ke view
        $html = view('transactions/invoice', [
            'data'    => $permintaanCustom,
            'items'    => $items,
            'riwayatPerubahanModel'    => $this->riwayatPerubahanModel,
        ]);

        // 🔹 setup Dompdf
        $options = new Options();
        $options->set('isRemoteEnabled', true); // biar bisa load CSS/IMG eksternal
        $dompdf = new Dompdf($options);

        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4', 'portrait'); // atau landscape
        $dompdf->render();

        // 🔹 output ke browser (stream) atau download
        return $dompdf->stream("invoice-{$permintaanCustom->created_at}.pdf", ["Attachment" => false]);
    }

    public function confirm_order($id)
    {
        if ($this->request->getMethod() == 'POST') {
            $request = $this->request;

            $data = [
                'status' => 1,
            ];

            $this->permintaanCustom->update($id, $data);

            session()->setFlashdata('success', 'Konfirmasi Pesanan Berhasil');
            return redirect()->to('/permintaan_custom');
        }

        $data['title'] = 'Konfirmasi Pesanan';
        $builder = $this->permintaanCustom->builder();
        $builder->select('tabel_permintaan_custom.*,tabel_customer.nama');
        $builder->join('tabel_customer', 'tabel_customer.id_customer = tabel_permintaan_custom.id_customer', 'inner');
        $builder->where('tabel_permintaan_custom.kode_permintaan_custom', $id);
        $permintaanCustom = $builder->orderBy('tabel_permintaan_custom.created_at', 'desc')->get()->getRow();
        $data['data'] = $permintaanCustom;

        $builder = $this->detailPermintaan->builder();
        $builder->select('tabel_detail_permintaan.*,tabel_detail_kain.*,tabel_jenis_kain.nama_jenis_kain,tabel_jenis_kain.warna,tabel_jenis_kain.foto_jenis_kain,tabel_model.nama_model,tabel_model.foto_model');
        $builder->join('tabel_detail_kain', 'tabel_detail_kain.id_detail_order = tabel_detail_permintaan.id_detail_order', 'inner');
        $builder->join('tabel_jenis_kain', 'tabel_jenis_kain.kode_jenis_kain = tabel_detail_kain.kode_jenis_kain', 'inner');
        $builder->join('tabel_model', 'tabel_model.kode_model = tabel_detail_permintaan.kode_model', 'inner');
        $builder->where('tabel_detail_permintaan.no_order_custom', $permintaanCustom->no_order_custom);
        $data['detail_model'] = $builder->orderBy('tabel_detail_permintaan.created_at', 'desc')->get()->getResult();
        $data['riwayatPerubahanModel'] = $this->riwayatPerubahanModel;

        return view('permintaan_custom/detail', $data);
    }

    /**
     * Get payment timeline / history untuk order
     */
    public function paymentTimeline($id)
    {
        $order = $this->permintaanCustom->find($id);
        if (!$order) {
            return $this->response->setStatusCode(404)->setJSON(['status' => 'error', 'message' => 'Order tidak ditemukan']);
        }

        $timeline = [
            'no_order' => $order->no_order_custom,
            'total_nominal' => $order->nominal_pelunasan,
            'dp_paid' => $order->dp_pembayaran,
            'remaining' => $order->sisa_pembayaran,
            'payment_status' => ($order->sisa_pembayaran == 0) ? 'Lunas' : 'DP',
            'payment_method' => $order->metode_pembayaran ?? 'Belum ditentukan',
            'payment_date' => $order->tanggal_pelunasan,
            'confirmed_at' => $order->tgl_kasir_konfirmasi,
        ];

        return $this->response->setJSON($timeline);
    }

    /**
     * Validate payment amount sebelum proses
     */
    public function validatePayment($id)
    {
        $order = $this->permintaanCustom->find($id);
        if (!$order) {
            return $this->response->setStatusCode(404)->setJSON(['status' => 'error', 'message' => 'Order tidak ditemukan']);
        }

        $jumlah = (float) $this->request->getPost('jumlah_bayar');

        if ($jumlah <= 0) {
            return $this->response->setJSON([
                'valid' => false,
                'message' => 'Jumlah pembayaran harus lebih dari 0'
            ]);
        }

        if ($jumlah > $order->nominal_pelunasan) {
            return $this->response->setJSON([
                'valid' => false,
                'message' => 'Jumlah pembayaran melebihi nominal pesanan'
            ]);
        }

        $sisa = $order->nominal_pelunasan - $jumlah;
        return $this->response->setJSON([
            'valid' => true,
            'message' => 'Pembayaran valid',
            'will_be_paid' => $jumlah,
            'remaining_after' => $sisa,
            'status_after' => ($sisa == 0) ? 'Lunas' : 'DP'
        ]);
    }

    /**
     * Update payment date when customer completes full payment
     * Hanya kasir yang bisa update tanggal pelunasan
     */
    public function updatePaymentDate($id)
    {
        if (auth()->user()->role != 'kasir') {
            return $this->response->setStatusCode(403)->setJSON(['status' => 'error', 'message' => 'Unauthorized']);
        }

        $tanggal_pelunasan = $this->request->getPost('tanggal_pelunasan');
        if (!$tanggal_pelunasan) {
            return $this->response->setStatusCode(400)->setJSON(['status' => 'error', 'message' => 'Tanggal pelunasan diperlukan']);
        }

        $this->permintaanCustom->update($id, ['tanggal_pelunasan' => $tanggal_pelunasan]);
        return $this->response->setJSON(['status' => 'success', 'message' => 'Tanggal pelunasan diperbarui']);
    }
}
