<?php

namespace App\Http\Controllers\Pemohon;

use App\Http\Controllers\Controller;
use App\Models\Buku;
use App\Models\MaklumatBukuDarjah;
use App\Models\Pengesahan;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class JumlahBukuController extends Controller
{
    public function __construct()
    {
        $this->middleware(['auth', 'role:pemohon']);
    }

    public function index(Request $request)
    {
        $user = Auth::user();
        $jenisSekolahList = $user->jenis_sekolah ?? [];
        $darjah = $request->query('darjah');
        $tahun = (int) $request->query('tahun', date('Y'));

        // Auto-detect jenis_sekolah dari darjah yang dipilih
        if ($darjah && !$request->has('jenis_sekolah')) {
            $bukuJenis = Buku::where('darjah', $darjah)->whereNotNull('jenis_sekolah')->value('jenis_sekolah');
            $jenisSekolah = $bukuJenis ?? ($jenisSekolahList[0] ?? null);
        } else {
            $jenisSekolah = $request->query('jenis_sekolah', $jenisSekolahList[0] ?? null);
        }

        $query = Buku::orderBy('darjah')->orderBy('kod_buku');
        if ($darjah) {
            $query->where('darjah', $darjah);
        }
        // Filter buku mengikut jenis sekolah (jika buku ada jenis_sekolah, tapis; jika null, papar semua)
        if ($jenisSekolah) {
            $query->where(function ($q) use ($jenisSekolah) {
                $q->where('jenis_sekolah', $jenisSekolah)
                  ->orWhereNull('jenis_sekolah');
            });
        }
        $bukus = $query->get();

        // Data sedia ada dari maklumat_buku_darjah untuk jenis sekolah ini
        $maklumatSaya = MaklumatBukuDarjah::where('user_id', $user->id)
            ->where('tahun', $tahun)
            ->where('jenis_sekolah', $jenisSekolah)
            ->get()
            ->keyBy('kod_buku');

        // Progress: darjah yang sudah selesai untuk jenis sekolah ini
        $darjahSelesai = MaklumatBukuDarjah::where('user_id', $user->id)
            ->where('tahun', $tahun)
            ->where('jenis_sekolah', $jenisSekolah)
            ->distinct('darjah')
            ->pluck('darjah')
            ->unique()
            ->values();

        // Senarai darjah berdasarkan buku yang ada untuk jenis sekolah ini
        $spesifikDarjah = Buku::distinct()->where('jenis_sekolah', $jenisSekolah)->orderBy('darjah')->pluck('darjah');
        $senaraiDarjah = $spesifikDarjah->isNotEmpty()
            ? $spesifikDarjah
            : Buku::distinct()->whereNull('jenis_sekolah')->orderBy('darjah')->pluck('darjah');

        // Progress per jenis sekolah — setiap jenis ada senarai darjah sendiri
        $progressPerJenis = collect();
        $totalAll = 0;
        $selesaiAll = 0;
        foreach ($jenisSekolahList as $js) {
            $senarai = Buku::distinct()->orderBy('darjah')
                ->where(function ($q) use ($js) {
                    $q->where('jenis_sekolah', $js)
                      ->orWhereNull('jenis_sekolah');
                })
                ->pluck('darjah');

            // Untuk jenis yang ada buku spesifik (cth KKM → TING*), tapis supaya hanya tunjuk darjah spesifik
            $spesifik = Buku::distinct()->where('jenis_sekolah', $js)->pluck('darjah');
            if ($spesifik->isNotEmpty()) {
                $senarai = $spesifik->sort()->values();
            }

            $selesai = MaklumatBukuDarjah::where('user_id', $user->id)
                ->where('tahun', $tahun)
                ->where('jenis_sekolah', $js)
                ->distinct('darjah')
                ->pluck('darjah')
                ->unique()
                ->values();

            $progressPerJenis[$js] = [
                'senarai' => $senarai,
                'selesai' => $selesai,
            ];
            $totalAll += $senarai->count();
            $selesaiAll += $selesai->count();
        }

        $totalDarjah = $senaraiDarjah->count();
        $selesaiCount = $darjahSelesai->count();
        $progressPct = $totalAll > 0
            ? round(($selesaiAll / $totalAll) * 100)
            : 0;

        // Status untuk darjah yang dipilih
        $selesai = $darjah ? $darjahSelesai->contains($darjah) : false;

        // Semak sama ada pengesahan untuk jenis_sekolah + tahun ini telah diluluskan
        // Jika supervisor telah berikan kebenaran edit semula (boleh_edit_semula=true),
        // anggap rekod tidak "disahkan" supaya pemohon boleh kemaskini.
        $disahkan = $jenisSekolah && Pengesahan::where('user_id', $user->id)
            ->where('tahun', $tahun)
            ->where('jenis_sekolah', $jenisSekolah)
            ->where('status', 'lulus')
            ->where('boleh_edit_semula', false)
            ->exists();

        // Edit mode: pengguna klik butang Edit selepas simpan (hanya jika belum disahkan)
        $editMode = $selesai && !$disahkan && $request->query('edit') === '1';
        if ($editMode) {
            $selesai = false;
        }

        return view('pemohon.jumlah_buku.index', compact(
            'bukus', 'maklumatSaya', 'darjah', 'tahun',
            'senaraiDarjah', 'totalDarjah', 'selesaiCount',
            'progressPct', 'darjahSelesai', 'selesai',
            'jenisSekolahList', 'jenisSekolah',
            'progressPerJenis', 'editMode', 'disahkan'
        ));
    }

    public function store(Request $request)
    {
        $request->validate([
            'jumlah'                      => 'required|array',
            'jumlah.*'                    => 'required|integer|min:0',
            'tahun'                       => 'required|integer|min:2026|max:2040',
            'darjah'                      => 'required|string',
            'jenis_sekolah'               => 'required|string',
            'unjuran_enrolmen'            => 'required|array',
            'unjuran_enrolmen.*'          => 'required|integer|min:0',
            'baki_buku_boss'              => 'required|array',
            'baki_buku_boss.*'            => 'required|integer|min:0',
            'buku_elok_boss'              => 'required|array',
            'buku_elok_boss.*'            => 'required|integer|min:0',
            'anggaran_buku_elok_tangan'   => 'required|array',
            'anggaran_buku_elok_tangan.*' => 'required|integer|min:0',
        ]);

        $userId = Auth::id();
        $tahun  = (int) $request->input('tahun');
        $darjah = $request->input('darjah');
        $jenisSekolah = $request->input('jenis_sekolah');

        $isEdit = $request->input('_edit') === '1';

        // Sekat edit jika pengesahan telah diluluskan oleh checker,
        // melainkan supervisor telah berikan kebenaran edit semula.
        if ($isEdit && Pengesahan::where('user_id', $userId)->where('tahun', $tahun)->where('jenis_sekolah', $jenisSekolah)->where('status', 'lulus')->where('boleh_edit_semula', false)->exists()) {
            return back()->with('error', 'Pendaftaran ' . $darjah . ' (' . $jenisSekolah . ') bagi tahun ' . $tahun . ' telah disahkan oleh penyemak. Kemaskini tidak dibenarkan.');
        }

        // Semak jika sudah pernah daftar untuk jenis sekolah ini
        if (!$isEdit && MaklumatBukuDarjah::where('user_id', $userId)->where('tahun', $tahun)->where('darjah', $darjah)->where('jenis_sekolah', $jenisSekolah)->exists()) {
            return back()->with('error', 'Pendaftaran ' . $darjah . ' (' . $jenisSekolah . ') bagi tahun ' . $tahun . ' telah pun dibuat. Hanya boleh daftar sekali sahaja.');
        }

        // Edit mode: padam rekod lama sebelum simpan semula
        if ($isEdit) {
            MaklumatBukuDarjah::where('user_id', $userId)
                ->where('tahun', $tahun)
                ->where('darjah', $darjah)
                ->where('jenis_sekolah', $jenisSekolah)
                ->delete();
        }

        // Validasi: buku_elok_boss tidak boleh melebihi baki_buku_boss
        foreach ($request->buku_elok_boss as $kodBuku => $elokB) {
            $baki = (int) ($request->baki_buku_boss[$kodBuku] ?? 0);
            $elok = (int) $elokB;
            if ($elok > $baki) {
                return back()->withInput()->with('error', 'Buku Elok BOSS tidak boleh lebih dari Baki Buku BOSS jumlahnya (Kod Buku: ' . $kodBuku . ': Elok=' . $elok . ', Baki=' . $baki . ').');
            }
        }

        // Pre-fetch judul buku
        $bukuRecords = Buku::whereIn('kod_buku', array_keys($request->jumlah))
            ->get()->keyBy('kod_buku');

        foreach ($request->jumlah as $kodBuku => $jumlah) {
            $unjuran = (int) ($request->unjuran_enrolmen[$kodBuku] ?? 0);
            $baki    = (int) ($request->baki_buku_boss[$kodBuku] ?? 0);
            $elokB   = (int) ($request->buku_elok_boss[$kodBuku] ?? 0);
            $angg    = (int) ($request->anggaran_buku_elok_tangan[$kodBuku] ?? 0);
            $stok    = $baki + (int) $jumlah;
            $elok    = $elokB + $angg;
            $pesan   = max(0, $unjuran - $elok);
            $lebihan = max(0, $elok - $unjuran);

            MaklumatBukuDarjah::create([
                'user_id'                   => $userId,
                'tahun'                     => $tahun,
                'darjah'                    => $darjah,
                'kod_sekolah'               => Auth::user()->kod_sekolah,
                'jenis_sekolah'             => $jenisSekolah,
                'kod_buku'                  => $kodBuku,
                'judul'                     => $bukuRecords[$kodBuku]?->judul ?? '',
                'buku_di_tangan_murid'      => (int) $jumlah,
                'unjuran_enrolmen'          => $unjuran,
                'baki_buku_boss'            => $baki,
                'buku_elok_boss'            => $elokB,
                'anggaran_buku_elok_tangan' => $angg,
                'stok_hingga_akhir'         => $stok,
                'elok_hingga_akhir'         => $elok,
                'pesanan_buku'              => $pesan,
                'lebihan_buku'              => $lebihan,
            ]);
        }

        return redirect()->route('pemohon.jumlah-buku.index', ['jenis_sekolah' => $jenisSekolah, 'darjah' => $darjah, 'tahun' => $tahun])
            ->with('success', ($isEdit ? 'Kemaskini' : 'Pendaftaran') . ' ' . $darjah . ' (' . $jenisSekolah . ') bagi tahun ' . $tahun . ' berjaya ' . ($isEdit ? 'dikemaskini.' : 'disimpan.'));
    }
}
