<?php

namespace App\Controllers;

use App\Models\ProdukModel;
use App\Models\Master\ResellerModel;
use App\Models\Master\MaklonModel;

class Penjualan extends BaseController
{
    private ProdukModel   $produkModel;
    private ResellerModel $resellerModel;
    private MaklonModel   $maklonModel;

    public function __construct()
    {
        $this->produkModel   = new ProdukModel();
        $this->resellerModel = new ResellerModel();
        $this->maklonModel   = new MaklonModel();
    }

    // ─────────────────────────────────────────────────────────────
    // GET /penjualan  →  tampilan POS Kasir
    // ─────────────────────────────────────────────────────────────
    public function index(): string
    {
        $db = \Config\Database::connect();

        /* ── Produk aktif ── */
        $products = $db->query(
            "SELECT * FROM tb_produk WHERE status_produk = 'Aktif' ORDER BY nama_produk ASC"
        )->getResultArray();

        /* ── Reseller aktif + harga khusus per produk ── */
        $resellerRaw = $db->query(
            "SELECT * FROM tb_reseller WHERE status_reseller = 'Aktif' ORDER BY nama_reseller ASC"
        )->getResultArray();

        foreach ($resellerRaw as &$r) {
            // harga_khusus → array [ ['id_produk'=>X, 'harga_khusus'=>Y], ... ]
            $r['harga_khusus'] = $this->resellerModel->getHargaKhusus((int)$r['id_reseller']);
        }
        unset($r);

        /* ── Maklon aktif + harga khusus per produk ── */
        $maklonRaw = $db->query(
            "SELECT * FROM tb_maklon WHERE status_maklon = 'Aktif' ORDER BY nama_maklon ASC"
        )->getResultArray();

        foreach ($maklonRaw as &$m) {
            $m['harga_khusus'] = $this->maklonModel->getHargaKhusus((int)$m['id_maklon']);
        }
        unset($m);

        return view('penjualan/index', [
            'title'    => 'Penjualan – POS Kasir',
            'products' => $products,
            'reseller' => $resellerRaw,
            'maklon'   => $maklonRaw,
        ]);
    }

    // ─────────────────────────────────────────────────────────────
    // POST /penjualan/store-manual  (AJAX)
    // ─────────────────────────────────────────────────────────────
    public function storeManual(): \CodeIgniter\HTTP\ResponseInterface
    {
        if (! $this->request->isAJAX()) {
            return $this->response
                ->setStatusCode(403)
                ->setJSON(['success' => false, 'error' => 'Akses tidak diizinkan.']);
        }

        $body = $this->request->getJSON(true);

        if (empty($body)) {
            return $this->response->setJSON([
                'success' => false,
                'error'   => 'Request body kosong atau bukan JSON.',
            ]);
        }

        $channel     = trim($body['channel']      ?? 'pos');
        $catatan     = trim($body['catatan']      ?? '');
        $metodeBayar = trim($body['metode_bayar'] ?? 'Tunai / Cash');
        $diskon      = max(0, (float)($body['diskon']  ?? 0));
        $total       = max(0, (float)($body['total']   ?? 0));
        $bayar       = max(0, (float)($body['bayar']   ?? 0));
        $idMitra     = (int)($body['id_mitra']         ?? 0);
        $items       = $body['items'] ?? [];

        if (empty($items) || ! is_array($items)) {
            return $this->response->setJSON([
                'success' => false,
                'error'   => 'Keranjang kosong – tidak ada item untuk diproses.',
            ]);
        }

        foreach ($items as $i => $item) {
            $idProd = (int)($item['id_produk'] ?? 0);
            $qty    = (int)($item['qty']       ?? 0);
            if ($idProd <= 0 || $qty < 1) {
                return $this->response->setJSON([
                    'success' => false,
                    'error'   => "Data item ke-" . ($i + 1) . " tidak valid (id_produk={$idProd}, qty={$qty}).",
                ]);
            }
        }

        /* Map channel → jenis_penjualan */
        $jenisMap = [
            'pos'      => 'Ecer',
            'kasir'    => 'Ecer',
            'reseller' => 'Reseller',
            'maklon'   => 'Maklon',
        ];
        $jenisPenjualan = $jenisMap[$channel] ?? 'Ecer';

        $db = \Config\Database::connect();
        $db->transStart();

        try {
            $now           = date('Y-m-d H:i:s');
            $today         = date('Y-m-d');
            $kodePenjualan = 'TRX-' . date('Ymd') . '-' . strtoupper(substr(uniqid(), -5));

            /* ── 1. Header penjualan ── */
            $db->query(
                "INSERT INTO tb_penjualan
                    (kode_penjualan, tanggal_penjualan, jenis_penjualan,
                     id_reseller, id_maklon,
                     total_penjualan, catatan_penjualan,
                     created_at, updated_at)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
                [
                    $kodePenjualan,
                    $today,
                    $jenisPenjualan,
                    ($jenisPenjualan === 'Reseller' && $idMitra > 0) ? $idMitra : null,
                    ($jenisPenjualan === 'Maklon'   && $idMitra > 0) ? $idMitra : null,
                    $total,
                    $catatan ?: null,
                    $now,
                    $now,
                ]
            );

            $idPenjualan = (int) $db->insertID();

            if ($idPenjualan <= 0) {
                throw new \RuntimeException('Gagal menyimpan header penjualan.');
            }

            /* ── 2. Item + kurangi stok ── */
            foreach ($items as $item) {
                $idProduk = (int)($item['id_produk']   ?? 0);
                $qty      = (int)($item['qty']          ?? 0);
                $harga    = (float)($item['harga_jual'] ?? 0);
                $subtotal = (float)($item['subtotal']   ?? $harga * $qty);

                $db->query(
                    "INSERT INTO tb_penjualan_item
                        (id_penjualan, id_produk, qty, harga_jual, subtotal, created_at)
                     VALUES (?, ?, ?, ?, ?, ?)",
                    [$idPenjualan, $idProduk, $qty, $harga, $subtotal, $now]
                );

                $ok = $this->produkModel->kurangiStok(
                    $idProduk,
                    $qty,
                    "Terjual – {$kodePenjualan}"
                );

                if (! $ok) {
                    throw new \RuntimeException(
                        "Stok produk ID {$idProduk} tidak mencukupi untuk qty {$qty}."
                    );
                }
            }

            $db->transComplete();

            if ($db->transStatus() === false) {
                throw new \RuntimeException('Transaksi database gagal di-commit.');
            }

            return $this->response->setJSON([
                'success'      => true,
                'no_transaksi' => $kodePenjualan,
                'id_penjualan' => $idPenjualan,
                'items_count'  => count($items),
                'message'      => "Transaksi {$kodePenjualan} berhasil disimpan.",
            ]);

        } catch (\Throwable $e) {
            $db->transRollback();
            log_message('error', '[Penjualan::storeManual] ' . $e->getMessage());

            return $this->response->setJSON([
                'success' => false,
                'error'   => $e->getMessage(),
            ]);
        }
    }

    public function storeMitra(): \CodeIgniter\HTTP\ResponseInterface
    {
        return $this->storeManual();
    }
}