<?php

namespace App\Libraries;

use App\Models\ProductionQueueModel;
use App\Models\ProductionQueueHistoryModel;
use App\Models\CompanySettingsModel;
use App\Services\MonthlyPoScheduler;
use Config\Database;

class QueueService
{
    protected $queue;
    protected $history;
    protected $settings;
    protected $db;

   public function __construct() {
    $this->queue    = new ProductionQueueModel();
    $this->history  = new ProductionQueueHistoryModel();
    $this->settings = new \App\Models\CompanySettingModel(); // Pastikan namespace benar
    $this->db       = Database::connect();
}

    /**
     * Mengambil limit bulanan dari database settings
     */
  public function getLimit(): int
{
    $setting = $this->settings->first();
    
    // DEBUG: Hapus baris di bawah ini jika sudah selesai testing
    // die(var_dump($setting)); 
    
    // Pastikan key array di bawah SAMA PERSIS dengan nama kolom di database
    return (int) ($setting['monthly_po_limit'] ?? 5);
}

public function updateLimit(int $newLimit): bool
{
    $db = \Config\Database::connect();
    $db->transBegin();

    try {
        $updated = $db->table('company_settings')
            ->where('id_setting', 1)
            ->update(['monthly_po_limit' => $newLimit]);

        if (! $updated) {
            throw new \RuntimeException('Limit bulanan gagal diperbarui.');
        }

        (new MonthlyPoScheduler($db))->rebalance($newLimit);
        if ($db->transStatus() === false) {
            throw new \RuntimeException('Penyesuaian jadwal PO gagal disimpan.');
        }
        $db->transCommit();

        return true;
    } catch (\Throwable $e) {
        $db->transRollback();
        log_message('error', $e->getMessage());

        return false;
    }
}
    /**
     * Membuat queue dengan mempertimbangkan kapasitas bulan berjalan
     */
    public function generateQueue(int $idOrder, int $idProduct, int $qtyOrder, ?string $tanggalProduksi = null): bool
    {
        $limit       = $this->getLimit();
        $currentDate = new \DateTime($tanggalProduksi ?? date('Y-m-d'));
        
        $this->db->transStart();
        $remaining = $qtyOrder;

        while ($remaining > 0) {
            $periode = $currentDate->format('Y-m');
            
            // Hitung total kuota yang sudah terpakai di periode tersebut
            $totalTerpakai = $this->queue->where('periode', $periode)
                                          ->whereNotIn('status', ['cancel'])
                                          ->selectSum('qty_hari_ini', 'total')
                                          ->get()->getRow()->total ?? 0;
            
            $kapasitasSisa = max(0, $limit - (int)$totalTerpakai);

            // Jika bulan ini penuh, pindah ke bulan berikutnya
            if ($kapasitasSisa <= 0) {
                $currentDate->modify('+1 month');
                continue;
            }

            $qtyThisPeriod = min($remaining, $kapasitasSisa);
            
            $queueId = $this->queue->insert([
                'id_order'         => $idOrder,
                'id_product'       => $idProduct,
                'qty_order'        => $qtyOrder,
                'qty_hari_ini'     => $qtyThisPeriod,
                'qty_sisa'         => $remaining - $qtyThisPeriod,
                'tanggal_produksi' => $currentDate->format('Y-m-d'),
                'periode'          => $periode,
                'status'           => 'waiting'
            ], true);

            $this->logHistory($queueId, '-', 'waiting');
            $remaining -= $qtyThisPeriod;
            
            if ($remaining > 0) {
                $currentDate->modify('+1 month');
            }
        }

        $this->db->transComplete();
        return $this->db->transStatus();
    }

    /**
     * Update status dengan pencatatan histori
     */
    public function updateStatus(int $idQueue, string $status): bool
    {
        $queue = $this->queue->find($idQueue);
        if (!$queue) return false;

        $normalizedStatus = $this->queue->normalizeQueueStatus($status);

        $this->db->transStart();
        $this->queue->update($idQueue, ['status' => $normalizedStatus]);
        $this->logHistory($idQueue, $queue['status'], $normalizedStatus);
        $this->db->transComplete();

        return $this->db->transStatus();
    }

    /**
     * Selesaikan queue
     */
    public function finishQueue(int $idQueue): bool
    {
        $queue = $this->queue->find($idQueue);
        if (!$queue) return false;

        $this->db->transStart();
        $this->queue->update($idQueue, ['status' => 'selesai', 'qty_sisa' => 0]);
        $this->logHistory($idQueue, $queue['status'], 'selesai');
        $this->db->transComplete();

        return $this->db->transStatus();
    }

    /**
     * Helper log histori
     */
    private function logHistory(int $idQueue, string $before, string $after): void
    {
        $this->history->insert([
            'id_queue'       => $idQueue,
            'status_sebelum' => $before,
            'status_sesudah' => $after,
            'updated_at'     => date('Y-m-d H:i:s')
        ]);
    }

    /**
     * Statistik dashboard
     */
    public function dashboard(): array
    {
        $stats = $this->queue->select('status, count(*) as count')
                             ->groupBy('status')
                             ->findAll();

        $result = ['waiting' => 0, 'process' => 0, 'completed' => 0, 'cancel' => 0];
        foreach ($stats as $row) {
            $result[$row['status']] = (int) $row['count'];
        }
        return $result;
    }
}
