<?php

namespace App\Models;

use CodeIgniter\Database\BaseConnection;

class ProdukModel
{
    protected BaseConnection $db;

    public function __construct()
    {
        $this->db = \Config\Database::connect();
    }

    // ────────────────────────────────────────────────────────────
    // findAll() — kompatibilitas dengan controller yang pakai CI Model style
    // ────────────────────────────────────────────────────────────
    public function findAll(): array
    {
        return $this->db->query(
            "SELECT
                id_produk,
                kode_produk,
                nama_produk,
                berat_produk,
                harga_produk,
                stok_produk,
                status_produk,
                keterangan_produk,
                created_at,
                updated_at
             FROM tb_produk
             WHERE deleted_at IS NULL
             ORDER BY nama_produk ASC"
        )->getResultArray();
    }

    // ────────────────────────────────────────────────────────────
    // Semua produk + ringkasan mutasi stok
    // ────────────────────────────────────────────────────────────
    public function getAllWithLog(bool $includeNonaktif = false): array
    {
        $whereStatus = $includeNonaktif
            ? "WHERE p.deleted_at IS NULL"
            : "WHERE p.status_produk = 'Aktif' AND p.deleted_at IS NULL";

        $sql = "
            SELECT
                p.id_produk                                         AS id,
                p.kode_produk                                       AS kode,
                p.nama_produk                                       AS nama,
                p.berat_produk                                      AS berat_gram,
                p.harga_produk                                      AS harga_jual,
                p.stok_produk                                       AS stok,
                p.status_produk,
                p.keterangan_produk                                 AS keterangan,
                p.created_at,
                p.updated_at,
                CASE WHEN p.status_produk = 'Aktif'
                     THEN 1 ELSE 0 END                              AS is_aktif,
                COALESCE(SUM(
                    CASE WHEN sl.tipe_stok_produk_log = 'masuk'
                    THEN sl.jumlah_stok_produk_log ELSE 0 END
                ), 0)                                               AS total_masuk,
                COALESCE(SUM(
                    CASE WHEN sl.tipe_stok_produk_log = 'keluar'
                    THEN sl.jumlah_stok_produk_log ELSE 0 END
                ), 0)                                               AS total_keluar
            FROM tb_produk p
            LEFT JOIN tb_stok_produk_log sl ON sl.id_produk = p.id_produk
            {$whereStatus}
            GROUP BY
                p.id_produk, p.kode_produk, p.nama_produk,
                p.berat_produk, p.harga_produk, p.stok_produk,
                p.status_produk, p.keterangan_produk,
                p.created_at, p.updated_at
            ORDER BY
                CASE WHEN p.status_produk = 'Aktif' THEN 0 ELSE 1 END ASC,
                p.nama_produk ASC
        ";

        return $this->db->query($sql)->getResultArray();
    }

    // ────────────────────────────────────────────────────────────
    // Cari 1 produk by ID
    // ────────────────────────────────────────────────────────────
    public function findById(int $id): ?array
    {
        $row = $this->db->query("
            SELECT
                id_produk           AS id,
                kode_produk         AS kode,
                nama_produk         AS nama,
                berat_produk        AS berat_gram,
                harga_produk        AS harga_jual,
                stok_produk         AS stok,
                status_produk,
                keterangan_produk   AS keterangan
            FROM tb_produk
            WHERE id_produk = ?
              AND deleted_at IS NULL
            LIMIT 1
        ", [$id])->getRowArray();

        return $row ?: null;
    }

    // ────────────────────────────────────────────────────────────
    // Cek apakah kode sudah dipakai produk lain
    // ────────────────────────────────────────────────────────────
    public function isKodeTaken(string $kode, int $excludeId = 0): bool
    {
        $sql    = "SELECT COUNT(*) AS cnt FROM tb_produk WHERE kode_produk = ? AND deleted_at IS NULL";
        $params = [$kode];

        if ($excludeId > 0) {
            $sql     .= " AND id_produk != ?";
            $params[] = $excludeId;
        }

        $row = $this->db->query($sql, $params)->getRowArray();
        return (int)($row['cnt'] ?? 0) > 0;
    }

    // ────────────────────────────────────────────────────────────
    // INSERT produk baru
    // ────────────────────────────────────────────────────────────
    public function insertProduk(array $data): int
    {
        $now = date('Y-m-d H:i:s');

        $this->db->query(
            "INSERT INTO tb_produk
                (kode_produk, nama_produk, berat_produk, harga_produk,
                 stok_produk, status_produk, keterangan_produk, created_at, updated_at)
             VALUES (?, ?, ?, ?, 0, 'Aktif', ?, ?, ?)",
            [
                $data['kode'],
                $data['nama'],
                (int)$data['berat_gram'],
                (float)$data['harga_jual'],
                $data['keterangan'] ?? '',
                $now,
                $now,
            ]
        );

        return (int)$this->db->insertID();
    }

    // ────────────────────────────────────────────────────────────
    // UPDATE produk
    // ────────────────────────────────────────────────────────────
    public function updateProduk(int $id, array $data): void
    {
        $this->db->query(
            "UPDATE tb_produk
             SET kode_produk        = ?,
                 nama_produk        = ?,
                 berat_produk       = ?,
                 harga_produk       = ?,
                 keterangan_produk  = ?,
                 updated_at         = ?
             WHERE id_produk = ?
               AND deleted_at IS NULL",
            [
                $data['kode'],
                $data['nama'],
                (int)$data['berat_gram'],
                (float)$data['harga_jual'],
                $data['keterangan'] ?? '',
                date('Y-m-d H:i:s'),
                $id,
            ]
        );
    }

    // ────────────────────────────────────────────────────────────
    // NONAKTIFKAN produk
    // ────────────────────────────────────────────────────────────
    public function nonaktifkan(int $id): void
    {
        $this->db->query(
            "UPDATE tb_produk SET status_produk = 'Non-Aktif', updated_at = ? WHERE id_produk = ?",
            [date('Y-m-d H:i:s'), $id]
        );
    }

    // ────────────────────────────────────────────────────────────
    // AKTIFKAN kembali produk
    // ────────────────────────────────────────────────────────────
    public function aktifkan(int $id): void
    {
        $this->db->query(
            "UPDATE tb_produk SET status_produk = 'Aktif', updated_at = ? WHERE id_produk = ?",
            [date('Y-m-d H:i:s'), $id]
        );
    }

    // ────────────────────────────────────────────────────────────
    // TAMBAH STOK
    // ────────────────────────────────────────────────────────────
    public function tambahStok(int $idProduk, int $jumlah, string $keterangan = 'Produksi'): void
    {
        $tanggal = date('Y-m-d');
        $now     = date('Y-m-d H:i:s');

        $this->db->query(
            "UPDATE tb_produk SET stok_produk = stok_produk + ?, updated_at = ? WHERE id_produk = ?",
            [$jumlah, $now, $idProduk]
        );

        $this->db->query(
            "INSERT INTO tb_stok_produk_log
                (id_produk, tanggal_stok_produk_log, tipe_stok_produk_log,
                 jumlah_stok_produk_log, keterangan_stok_produk_log, created_at)
             VALUES (?, ?, 'masuk', ?, ?, ?)",
            [$idProduk, $tanggal, $jumlah, $keterangan, $now]
        );
    }

    // ────────────────────────────────────────────────────────────
    // KURANGI STOK
    // ────────────────────────────────────────────────────────────
    public function kurangiStok(int $idProduk, int $jumlah, string $keterangan = 'Terjual'): bool
    {
        $row = $this->db->query(
            "SELECT stok_produk FROM tb_produk WHERE id_produk = ? LIMIT 1",
            [$idProduk]
        )->getRowArray();

        if (! $row || (int)$row['stok_produk'] < $jumlah) {
            return false;
        }

        $tanggal = date('Y-m-d');
        $now     = date('Y-m-d H:i:s');

        $this->db->query(
            "UPDATE tb_produk SET stok_produk = stok_produk - ?, updated_at = ? WHERE id_produk = ?",
            [$jumlah, $now, $idProduk]
        );

        $this->db->query(
            "INSERT INTO tb_stok_produk_log
                (id_produk, tanggal_stok_produk_log, tipe_stok_produk_log,
                 jumlah_stok_produk_log, keterangan_stok_produk_log, created_at)
             VALUES (?, ?, 'keluar', ?, ?, ?)",
            [$idProduk, $tanggal, $jumlah, $keterangan, $now]
        );

        return true;
    }

    // ────────────────────────────────────────────────────────────
    // LOG MUTASI
    // ────────────────────────────────────────────────────────────
    public function getLog(int $idProduk = 0, int $limit = 50): array
    {
        $sql    = "
            SELECT
                sl.id_stok_produk_log                       AS id,
                sl.id_produk,
                sl.tanggal_stok_produk_log                  AS tanggal,
                sl.tipe_stok_produk_log                     AS tipe,
                sl.jumlah_stok_produk_log                   AS jumlah,
                sl.keterangan_stok_produk_log               AS keterangan,
                sl.created_at,
                p.nama_produk                               AS nama_produk
            FROM tb_stok_produk_log sl
            JOIN tb_produk p ON p.id_produk = sl.id_produk
        ";
        $params = [];

        if ($idProduk > 0) {
            $sql     .= " WHERE sl.id_produk = ?";
            $params[] = $idProduk;
        }

        $sql .= " ORDER BY sl.created_at DESC, sl.id_stok_produk_log DESC LIMIT " . (int)$limit;

        return $this->db->query($sql, $params)->getResultArray();
    }

    // ────────────────────────────────────────────────────────────
    // Dropdown produk aktif (untuk resep dll)
    // ────────────────────────────────────────────────────────────
    public function getProdukAktif(): array
    {
        return $this->db->query(
            "SELECT id_produk, nama_produk, kode_produk, harga_produk, berat_produk
         FROM tb_produk
         WHERE status_produk = 'Aktif'
           AND deleted_at IS NULL
         ORDER BY nama_produk ASC"
        )->getResultArray();
    }
}
