<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use App\Models\TransaksiKasModel;
use App\Models\PenggajianModel;
use App\Models\KaryawanModel;

class Finance extends BaseController
{
    protected $kasModel;
    protected $penggajianModel;
    protected $karyawanModel;

    public function __construct()
    {
        $this->kasModel = new TransaksiKasModel();
        $this->penggajianModel = new PenggajianModel();
        $this->karyawanModel = new KaryawanModel();
    }

    // ================== VIEW ==================
    public function index()
    {
        $unpaidGaji = $this->penggajianModel
            ->select('tb_penggajian.*, tb_karyawan.nama_karyawan')
            ->join('tb_karyawan', 'tb_karyawan.id_karyawan = tb_penggajian.id_karyawan')
            ->where('tb_penggajian.status_pembayaran_penggajian', 'Belum Dibayar')
            ->orderBy('tb_penggajian.periode_bulan_penggajian', 'ASC')
            ->findAll();

        $data = [
            'transaksi'  => $this->kasModel
                ->orderBy('tanggal_transaksi_kas', 'DESC')
                ->orderBy('id_transaksi_kas', 'DESC')
                ->findAll(),
            'saldo'      => $this->getSaldoAkhir(),
            'unpaidGaji' => $unpaidGaji
        ];

        return view('finance/pengeluaran', $data);
    }

    // ================== HITUNG SALDO ==================
    private function getSaldoAkhir()
    {
        $data = $this->kasModel->findAll();

        $saldo = 0;

        foreach ($data as $row) {
            if ($row['tipe_transaksi_kas'] == 'Pemasukan') {
                $saldo += $row['nominal_transaksi_kas'];
            } else {
                $saldo -= $row['nominal_transaksi_kas'];
            }
        }

        return $saldo;
    }

    // ================== CORE INSERT KAS (UNTUK SEMUA MODULE) ==================
    public function insertKas(string $tipe, string $kategori, float $nominal, string $keterangan = '', string $tanggal = null)
    {
        $this->kasModel->insert([
            'tanggal_transaksi_kas'    => $tanggal ?? date('Y-m-d'),
            'tipe_transaksi_kas'       => $tipe,
            'kategori_transaksi_kas'   => $kategori,
            'nominal_transaksi_kas'    => $nominal,
            'keterangan_transaksi_kas' => $keterangan,
        ]);
    }

    // ================== FORM MANUAL ==================
    public function store()
    {
        $tanggal        = $this->request->getPost('tanggal');
        $tipe_transaksi = $this->request->getPost('tipe_transaksi');
        $kategori       = $this->request->getPost('kategori');
        $keterangan     = $this->request->getPost('keterangan');
        $nominal        = $this->request->getPost('nominal');
        $id_penggajian  = $this->request->getPost('id_penggajian');

        if (!$this->validate([
            'tanggal'        => 'required|valid_date',
            'tipe_transaksi' => 'required|in_list[Pemasukan,Pengeluaran]',
            'kategori'       => 'required'
        ])) {
            return redirect()->back()->withInput()->with('error', 'Cek kembali input.');
        }

        // ❌ BLOCK ERROR
        if ($tipe_transaksi === 'Pemasukan' && $kategori === 'Biaya Gaji / Upah Karyawan') {
            return redirect()->back()->withInput()->with('error', 'Gaji tidak boleh jadi pemasukan.');
        }

        // ================== GAJI ==================
        if ($tipe_transaksi === 'Pengeluaran' && $kategori === 'Biaya Gaji / Upah Karyawan') {

            if (empty($id_penggajian)) {
                return redirect()->back()->withInput()->with('error', 'Pilih slip gaji.');
            }

            $gajiTarget = $this->penggajianModel->find($id_penggajian);

            if (!$gajiTarget) {
                return redirect()->back()->withInput()->with('error', 'Data gaji tidak ditemukan.');
            }

            if ($gajiTarget['status_pembayaran_penggajian'] === 'Sudah Dibayar') {
                return redirect()->back()->with('error', 'Gaji sudah dibayar!');
            }

            $karyawan = $this->karyawanModel->find($gajiTarget['id_karyawan']);

            $nominalKas = $gajiTarget['total_gaji_penggajian'];

            $keteranganKas = "Pembayaran Gaji an. "
                . $karyawan['nama_karyawan']
                . " Periode "
                . $gajiTarget['periode_bulan_penggajian'];

            $this->insertKas(
                'Pengeluaran',
                'Biaya Gaji / Upah Karyawan',
                $nominalKas,
                $keteranganKas,
                $tanggal
            );

            $this->penggajianModel->update($id_penggajian, [
                'status_pembayaran_penggajian' => 'Sudah Dibayar'
            ]);

            return redirect()->to('/finance/pengeluaran')
                ->with('success', 'Gaji berhasil dibayar: Rp ' . number_format($nominalKas, 0, ',', '.'));
        }

        // ================== TRANSAKSI BIASA ==================
        if (empty($nominal) || !is_numeric($nominal) || $nominal <= 0) {
            return redirect()->back()->withInput()->with('error', 'Nominal tidak valid.');
        }

        $this->insertKas(
            $tipe_transaksi,
            $kategori,
            $nominal,
            $keterangan,
            $tanggal
        );

        return redirect()->to('/finance/pengeluaran')
            ->with('success', 'Transaksi berhasil ditambahkan!');
    }

    // ================== BUKU BESAR ==================
    public function bukuBesar()
    {
        $penjualanModel = new \App\Models\TransaksiPesananModel();

        $penjualan = $penjualanModel
            ->where('status_pesanan', 'Selesai')
            ->orderBy('create_time', 'DESC')
            ->findAll();

        $pengeluaran = $this->kasModel
            ->where('tipe_transaksi_kas', 'Pengeluaran')
            ->orderBy('tanggal_transaksi_kas', 'DESC')
            ->findAll();

        $totalPemasukan   = array_sum(array_column($penjualan, 'total_amount'));
        $totalPengeluaran = array_sum(array_column($pengeluaran, 'nominal_transaksi_kas'));

        return view('buku_besar/index', [
            'penjualan'        => $penjualan,
            'pengeluaran'      => $pengeluaran,
            'totalPemasukan'   => $totalPemasukan,
            'totalPengeluaran' => $totalPengeluaran,
        ]);
    }
    // ================== LAPORAN KEUANGAN  ==================

    public function laporanKeuangan()
{
    $db = \Config\Database::connect();

    // ── Arus Kas: gabung kas manual + penjualan selesai ──
    $kasRows = $this->kasModel->orderBy('tanggal_transaksi_kas', 'DESC')->findAll();
    $penjualanRows = $db->query("
        SELECT DATE(create_time) as tgl, total_amount
        FROM transaksi_pesanan
        WHERE status_pesanan = 'Selesai' AND total_amount > 0
    ")->getResultArray();

    $arusKas = [];
    foreach ($kasRows as $k) {
        $arusKas[] = [
            'tanggal'    => $k['tanggal_transaksi_kas'],
            'tipe'       => $k['tipe_transaksi_kas'],
            'kategori'   => $k['kategori_transaksi_kas'],
            'keterangan' => $k['keterangan_transaksi_kas'],
            'nominal'    => $k['nominal_transaksi_kas'],
        ];
    }
    foreach ($penjualanRows as $p) {
        $arusKas[] = [
            'tanggal'    => $p['tgl'],
            'tipe'       => 'Pemasukan',
            'kategori'   => 'Pendapatan Penjualan',
            'keterangan' => 'Order TikTok/Marketplace',
            'nominal'    => $p['total_amount'],
        ];
    }
    usort($arusKas, fn($a, $b) => strcmp($b['tanggal'], $a['tanggal']));

    // ── Rekap kategori pengeluaran ──
    $rekapKategori = $db->query("
        SELECT kategori_transaksi_kas as kategori,
               SUM(nominal_transaksi_kas) as total,
               COUNT(*) as jumlah
        FROM tb_transaksi_kas
        WHERE tipe_transaksi_kas = 'Pengeluaran'
        GROUP BY kategori_transaksi_kas
        ORDER BY total DESC
    ")->getResultArray();

    // ── Saldo harian ──
    $harian = $db->query("
        SELECT tanggal_transaksi_kas as tgl,
               SUM(CASE WHEN tipe_transaksi_kas='Pemasukan' THEN nominal_transaksi_kas ELSE 0 END) as masuk,
               SUM(CASE WHEN tipe_transaksi_kas='Pengeluaran' THEN nominal_transaksi_kas ELSE 0 END) as keluar
        FROM tb_transaksi_kas
        GROUP BY tanggal_transaksi_kas
        ORDER BY tanggal_transaksi_kas ASC
    ")->getResultArray();

    $saldoHarian = [];
    $saldoBerjalan = 0;
    foreach ($harian as $h) {
        $saldoBerjalan += $h['masuk'] - $h['keluar'];
        $saldoHarian[] = [
            'tanggal'     => $h['tgl'],
            'pemasukan'   => $h['masuk'],
            'pengeluaran' => $h['keluar'],
            'saldo_akhir' => $saldoBerjalan,
        ];
    }
    $saldoHarian = array_reverse($saldoHarian);

    // ── Summary ──
    $totalPemasukan   = array_sum(array_column(array_filter($arusKas, fn($r) => $r['tipe'] === 'Pemasukan'), 'nominal'));
    $totalPengeluaran = array_sum(array_column(array_filter($arusKas, fn($r) => $r['tipe'] === 'Pengeluaran'), 'nominal'));
    $saldoBersih      = $totalPemasukan - $totalPengeluaran;

    $bulanIni = date('Y-m');
    $totalTransaksiBulanIni = count(array_filter($arusKas, fn($r) => substr($r['tanggal'], 0, 7) === $bulanIni));

    $daftarBulan = array_unique(array_map(fn($r) => substr($r['tanggal'], 0, 7), $arusKas));
    rsort($daftarBulan);

    return view('laporan_keuangan/index', [
        'arusKas'                => $arusKas,
        'rekapKategori'          => $rekapKategori,
        'saldoHarian'            => $saldoHarian,
        'totalPemasukan'         => $totalPemasukan,
        'totalPengeluaran'       => $totalPengeluaran,
        'saldoBersih'            => $saldoBersih,
        'totalTransaksiBulanIni' => $totalTransaksiBulanIni,
        'daftarBulan'            => $daftarBulan,
    ]);
}
}