<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class CreateProduksiTriggersAndViews extends Migration
{
    public function up(): void
    {
        // ----------------------------------------------------------------
        // TRIGGER 1: Cache biaya header saat detail di-INSERT
        // ----------------------------------------------------------------
        $this->db->query('DROP TRIGGER IF EXISTS `trg_detail_produksi_insert`');
        $this->db->query('
            CREATE TRIGGER `trg_detail_produksi_insert`
            AFTER INSERT ON `tb_detail_produksi`
            FOR EACH ROW
            BEGIN
                UPDATE `tb_produksi`
                SET
                    `total_biaya_bahan` = (
                        SELECT COALESCE(SUM(`subtotal_bahan`), 0)
                        FROM `tb_detail_produksi`
                        WHERE `id_produksi` = NEW.`id_produksi`
                    ),
                    `total_biaya` = (
                        SELECT COALESCE(SUM(`subtotal_bahan`), 0)
                        FROM `tb_detail_produksi`
                        WHERE `id_produksi` = NEW.`id_produksi`
                    ) + `biaya_tenaga` + `biaya_lain`,
                    `hpp_per_unit` = (
                        (
                            SELECT COALESCE(SUM(`subtotal_bahan`), 0)
                            FROM `tb_detail_produksi`
                            WHERE `id_produksi` = NEW.`id_produksi`
                        ) + `biaya_tenaga` + `biaya_lain`
                    ) / GREATEST(`jumlah_produksi`, 1),
                    `updated_at` = NOW()
                WHERE `id_produksi` = NEW.`id_produksi`;
            END
        ');

        // ----------------------------------------------------------------
        // TRIGGER 2: Cache biaya header saat detail di-UPDATE
        // ----------------------------------------------------------------
        $this->db->query('DROP TRIGGER IF EXISTS `trg_detail_produksi_update`');
        $this->db->query('
            CREATE TRIGGER `trg_detail_produksi_update`
            AFTER UPDATE ON `tb_detail_produksi`
            FOR EACH ROW
            BEGIN
                UPDATE `tb_produksi`
                SET
                    `total_biaya_bahan` = (
                        SELECT COALESCE(SUM(`subtotal_bahan`), 0)
                        FROM `tb_detail_produksi`
                        WHERE `id_produksi` = NEW.`id_produksi`
                    ),
                    `total_biaya` = (
                        SELECT COALESCE(SUM(`subtotal_bahan`), 0)
                        FROM `tb_detail_produksi`
                        WHERE `id_produksi` = NEW.`id_produksi`
                    ) + `biaya_tenaga` + `biaya_lain`,
                    `hpp_per_unit` = (
                        (
                            SELECT COALESCE(SUM(`subtotal_bahan`), 0)
                            FROM `tb_detail_produksi`
                            WHERE `id_produksi` = NEW.`id_produksi`
                        ) + `biaya_tenaga` + `biaya_lain`
                    ) / GREATEST(`jumlah_produksi`, 1),
                    `updated_at` = NOW()
                WHERE `id_produksi` = NEW.`id_produksi`;
            END
        ');

        // ----------------------------------------------------------------
        // TRIGGER 3 (UTAMA): Saat status_produksi -> 'selesai'
        // FIX: Dihapus INSERT tb_penggunaan_bahan karena tabel mungkin
        //      tidak ada sehingga menyebabkan "Transaksi database gagal".
        //      Logika stok kini dijalankan di PHP (ProduksiModel::simpan)
        //      dengan sudah_dikurangi=1 saat INSERT, sehingga kondisi
        //      dp.sudah_dikurangi = 0 di trigger ini tidak akan match
        //      dan trigger berjalan aman (no-op) tanpa double-deduct.
        // ----------------------------------------------------------------
        $this->db->query('DROP TRIGGER IF EXISTS `trg_produksi_selesai`');
        $this->db->query('
            CREATE TRIGGER `trg_produksi_selesai`
            AFTER UPDATE ON `tb_produksi`
            FOR EACH ROW
            BEGIN
                IF NEW.`status_produksi` = \'selesai\' AND OLD.`status_produksi` <> \'selesai\' THEN

                    -- Kurangi stok bahan (hanya jika sudah_dikurangi=0)
                    -- Karena PHP sudah set sudah_dikurangi=1 saat INSERT,
                    -- blok ini hanya aktif jika ada update manual dari draft->selesai
                    UPDATE `tb_bahan` b
                    INNER JOIN `tb_detail_produksi` dp ON dp.`id_bahan` = b.`id_bahan`
                    SET
                        b.`stok_bahan` = GREATEST(b.`stok_bahan` - dp.`jumlah_total`, 0),
                        b.`updated_at` = NOW()
                    WHERE dp.`id_produksi` = NEW.`id_produksi`
                      AND dp.`sudah_dikurangi` = 0;

                    -- Tambah stok produk (hanya jika ada bahan yang belum dikurangi)
                    -- Pakai variabel untuk cek apakah ada perubahan
                    SET @rows_updated = ROW_COUNT();

                    -- Tandai detail sudah diproses
                    UPDATE `tb_detail_produksi`
                    SET `sudah_dikurangi` = 1, `updated_at` = NOW()
                    WHERE `id_produksi` = NEW.`id_produksi`
                      AND `sudah_dikurangi` = 0;

                END IF;
            END
        ');

        // ----------------------------------------------------------------
        // VIEW 1: Ringkasan produksi + HPP + margin
        // ----------------------------------------------------------------
        $this->db->query('
            CREATE OR REPLACE VIEW `v_produksi_ringkasan` AS
            SELECT
                p.`id_produksi`,
                p.`kode_produksi`,
                p.`tanggal_produksi`,
                p.`status_produksi`,
                pr.`kode_produk`,
                pr.`nama_produk`,
                r.`nama_resep`,
                p.`jumlah_produksi`,
                p.`total_biaya_bahan`,
                p.`biaya_tenaga`,
                p.`biaya_lain`,
                p.`total_biaya`,
                p.`hpp_per_unit`,
                pr.`harga_produk`,
                (pr.`harga_produk` - p.`hpp_per_unit`) AS `margin_per_unit`,
                p.`diselesaikan_oleh`,
                p.`catatan_produksi`,
                p.`created_at`
            FROM `tb_produksi` p
            JOIN `tb_produk` pr ON pr.`id_produk` = p.`id_produk`
            JOIN `tb_resep`   r  ON r.`id_resep`  = p.`id_resep`
        ');

        // ----------------------------------------------------------------
        // VIEW 2: Detail bahan per produksi
        // ----------------------------------------------------------------
        $this->db->query('
            CREATE OR REPLACE VIEW `v_produksi_detail_bahan` AS
            SELECT
                dp.`id_detail_produksi`,
                p.`kode_produksi`,
                p.`status_produksi`,
                p.`tanggal_produksi`,
                b.`kode_bahan`,
                b.`nama_bahan`,
                b.`satuan_bahan`,
                dp.`jumlah_per_batch`,
                p.`jumlah_produksi`,
                dp.`jumlah_total`,
                dp.`harga_satuan_bahan`,
                dp.`subtotal_bahan`,
                dp.`sudah_dikurangi`,
                b.`stok_bahan` AS `stok_bahan_saat_ini`
            FROM `tb_detail_produksi` dp
            JOIN `tb_produksi` p ON p.`id_produksi` = dp.`id_produksi`
            JOIN `tb_bahan`    b ON b.`id_bahan`    = dp.`id_bahan`
        ');

        // ----------------------------------------------------------------
        // VIEW 3: Cek kecukupan stok sebelum produksi diselesaikan
        // ----------------------------------------------------------------
        $this->db->query('
            CREATE OR REPLACE VIEW `v_cek_stok_produksi` AS
            SELECT
                dp.`id_produksi`,
                p.`kode_produksi`,
                b.`nama_bahan`,
                b.`satuan_bahan`,
                dp.`jumlah_total`                        AS `kebutuhan`,
                b.`stok_bahan`                           AS `stok_tersedia`,
                (b.`stok_bahan` - dp.`jumlah_total`)     AS `selisih`,
                CASE
                    WHEN b.`stok_bahan` >= dp.`jumlah_total` THEN \'Cukup\'
                    ELSE \'KURANG\'
                END AS `status_stok`
            FROM `tb_detail_produksi` dp
            JOIN `tb_produksi` p ON p.`id_produksi` = dp.`id_produksi`
            JOIN `tb_bahan`    b ON b.`id_bahan`    = dp.`id_bahan`
            WHERE p.`status_produksi` IN (\'draft\', \'proses\')
        ');
    }

    public function down(): void
    {
        $this->db->query('DROP TRIGGER IF EXISTS `trg_detail_produksi_insert`');
        $this->db->query('DROP TRIGGER IF EXISTS `trg_detail_produksi_update`');
        $this->db->query('DROP TRIGGER IF EXISTS `trg_produksi_selesai`');
        $this->db->query('DROP VIEW IF EXISTS `v_produksi_ringkasan`');
        $this->db->query('DROP VIEW IF EXISTS `v_produksi_detail_bahan`');
        $this->db->query('DROP VIEW IF EXISTS `v_cek_stok_produksi`');
    }
}