<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\AcademicYearModel;
use App\Models\GradeModel;
use App\Models\GraduationSettingModel;
use App\Services\GraduationService;
use CodeIgniter\I18n\Time;

class Graduation extends BaseController
{
    protected $academicYearModel;
    protected $gradeModel;
    protected $graduationSettingModel;
    protected $graduationService;

    public function __construct()
    {
        $this->academicYearModel      = new AcademicYearModel();
        $this->gradeModel             = new GradeModel();
        $this->graduationSettingModel = new GraduationSettingModel();
        $this->graduationService      = new GraduationService();
    }

    private function checkLogin()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }
        return null;
    }

    // ── SETTING KELULUSAN ────────────────────────────────────────

    public function settings()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activeYear = $this->academicYearModel->getActive();

        if (!$activeYear) {
            return redirect()->to('/admin/academic-year')
                ->with('error', 'Belum ada Tahun Ajaran aktif. Harap tentukan Tahun Ajaran aktif terlebih dahulu.');
        }

        $settings = $this->graduationSettingModel->getSettingsByYear($activeYear['id']);

        $data = [
            'title'      => 'Pengaturan Kelulusan Online',
            'activeYear' => $activeYear,
            'grades'     => $this->gradeModel->orderBy('order', 'ASC')->findAll(),
            'settings'   => $settings,
        ];

        return view('admin/graduation/settings', $data);
    }

    public function saveSettings()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activeYear = $this->academicYearModel->getActive();

        if (!$activeYear) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Tidak ada Tahun Ajaran aktif.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        $rules = [
            'final_grade_id'      => 'required|integer',
            'announcement_date'   => 'required|valid_date',
            'announcement_time'   => 'required',
            'is_active'           => 'permit_empty|in_list[0,1]',
            'custom_message'      => 'permit_empty|max_length[500]',
        ];

        if (!$this->validate($rules)) {
            return $this->response->setJSON([
                'success' => false,
                'message' => implode(', ', $this->validator->getErrors()),
                'errors'  => $this->validator->getErrors(),
                'csrf_token' => csrf_hash(),
            ]);
        }

        $announcementDate = $this->request->getPost('announcement_date');
        $announcementTime = $this->request->getPost('announcement_time');

        try {
            $announcementDateTime = Time::parse("$announcementDate $announcementTime")->toDateTimeString();
        } catch (\Exception $e) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Format tanggal atau jam pengumuman tidak valid.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        $data = [
            'academic_year_id'        => $activeYear['id'],
            'final_grade_id'          => $this->request->getPost('final_grade_id'),
            'announcement_datetime'   => $announcementDateTime,
            'is_active'               => (int) $this->request->getPost('is_active'),
            'allow_skl_download'      => (int) $this->request->getPost('allow_skl_download'),
            'custom_message'          => $this->request->getPost('custom_message'),
        ];

        $existingSettings = $this->graduationSettingModel->getSettingsByYear($activeYear['id']);

        if ($existingSettings) {
            $this->graduationSettingModel->update($existingSettings['id'], $data);
        } else {
            $this->graduationSettingModel->insert($data);
        }

        log_activity('update', 'graduation_settings', $activeYear['id'], "Mengubah pengaturan kelulusan untuk TA {$activeYear['name']}");

        return $this->response->setJSON([
            'success' => true,
            'message' => 'Pengaturan kelulusan berhasil disimpan.',
            'csrf_token' => csrf_hash(),
        ]);
    }

    // ── DAFTAR SISWA (PENETAPAN KELULUSAN) ───────────────────────

    public function students()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activeYear = $this->academicYearModel->getActive();

        if (!$activeYear) {
            return redirect()->to('/admin/academic-year')
                ->with('error', 'Belum ada Tahun Ajaran aktif. Harap tentukan Tahun Ajaran aktif terlebih dahulu.');
        }

        $settings = $this->graduationSettingModel->getSettingsByYear($activeYear['id']);

        if (!$settings || empty($settings['final_grade_id'])) {
            return redirect()->to('/admin/graduation/settings')
                ->with('error', 'Harap tentukan kelas akhir di Pengaturan Kelulusan terlebih dahulu.');
        }

        $data = [
            'title'        => 'Daftar Siswa Kelulusan',
            'activeYear'   => $activeYear,
            'settings'     => $settings,
            'grades'       => $this->gradeModel->orderBy('order', 'ASC')->findAll(),
        ];

        return view('admin/graduation/students', $data);
    }

    public function getFinalYearStudentsAjax()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activeYear = $this->academicYearModel->getActive();

        if (!$activeYear) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Tidak ada Tahun Ajaran aktif.',
                'students' => [],
            ]);
        }

        $settings = $this->graduationSettingModel->getSettingsByYear($activeYear['id']);

        if (!$settings || empty($settings['final_grade_id'])) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Harap tentukan kelas akhir di Pengaturan Kelulusan terlebih dahulu.',
                'students' => [],
            ]);
        }

        $finalGradeId = $settings['final_grade_id'];
        $students     = $this->graduationService->getFinalYearStudents($activeYear['id'], $finalGradeId);

        return $this->response->setJSON([
            'success' => true,
            'students' => $students,
            'csrf_token' => csrf_hash(),
        ]);
    }

    public function bulkStatus()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $studentIds = $this->request->getPost('student_ids');
        $status     = $this->request->getPost('status');
        $decidedAt  = $this->request->getPost('decided_at') ?? Time::now()->toDateString();

        if (empty($studentIds) || !in_array($status, ['LULUS', 'TIDAK_LULUS'])) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Data tidak lengkap.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        $activeYear = $this->academicYearModel->getActive();
        if (!$activeYear) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Tidak ada Tahun Ajaran aktif.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        $userId = session()->get('user_id');
        $count  = $this->graduationService->processBulkGraduationDecision(
            array_map('intval', $studentIds),
            $status,
            $decidedAt,
            $activeYear['id'],
            (int)$userId
        );

        return $this->response->setJSON([
            'success' => true,
            'message' => "{$count} siswa berhasil ditetapkan status kelulusannya sebagai {$status}.",
            'csrf_token' => csrf_hash(),
        ]);
    }

    public function updateStatus(int $studentId)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $status    = $this->request->getPost('status'); // LULUS or TIDAK_LULUS
        $decidedAt = $this->request->getPost('decided_at') ?? Time::now()->toDateString();

        if (!in_array($status, ['LULUS', 'TIDAK_LULUS'])) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Status tidak valid.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        $activeYear = $this->academicYearModel->getActive();
        if (!$activeYear) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Tidak ada Tahun Ajaran aktif.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        $userId = session()->get('user_id');
        if ($this->graduationService->processGraduationDecision($studentId, $status, $decidedAt, $activeYear['id'], (int)$userId)) {
            return $this->response->setJSON([
                'success' => true,
                'message' => 'Status kelulusan berhasil diperbarui.',
                'csrf_token' => csrf_hash(),
            ]);
        } else {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Gagal memperbarui status kelulusan.',
                'csrf_token' => csrf_hash(),
            ]);
        }
    }

    // ── UPLOAD SKL & RINGKASAN ───────────────────────────────────

    public function uploadSkl()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activeYear = $this->academicYearModel->getActive();

        if (!$activeYear) {
            return redirect()->to('/admin/academic-year')
                ->with('error', 'Belum ada Tahun Ajaran aktif. Harap tentukan Tahun Ajaran aktif terlebih dahulu.');
        }

        $sklYears = $this->graduationService->getSklYears();

        $data = [
            'title'      => 'Upload & Manajemen SKL',
            'activeYear' => $activeYear,
            'summary'    => $this->graduationService->getSklSummary(),
            'sklYears'   => $sklYears,
        ];

        return view('admin/graduation/upload_skl', $data);
    }

    public function processSklUpload()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activeYear = $this->academicYearModel->getActive();
        if (!$activeYear) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Tidak ada Tahun Ajaran aktif.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        $validationRule = [
            'skl_zip_file' => [
                'label' => 'SKL ZIP File',
                'rules' => 'uploaded[skl_zip_file]|mime_in[skl_zip_file,application/zip]|max_size[skl_zip_file,40960]',
                'errors' => [
                    'uploaded' => 'File ZIP SKL wajib diupload.',
                    'mime_in'  => 'File harus berformat ZIP.',
                    'max_size' => 'Ukuran file ZIP tidak boleh melebihi 40MB.',
                ],
            ],
        ];

        if (!$this->validate($validationRule)) {
            return $this->response->setJSON([
                'success' => false,
                'message' => implode(', ', $this->validator->getErrors()),
                'errors'  => $this->validator->getErrors(),
                'csrf_token' => csrf_hash(),
            ]);
        }

        $zipFile = $this->request->getFile('skl_zip_file');
        $userId  = session()->get('user_id');

        $report = $this->graduationService->uploadSklZip($zipFile, $activeYear['id'], (int)$userId);

        return $this->response->setJSON(array_merge($report, [
            'success' => $report['failed_count'] === 0,
            'message' => $report['failed_count'] === 0 ?
                            "Berhasil upload {$report['success_count']} SKL." :
                            "Gagal upload {$report['failed_count']} SKL. Silakan cek laporan.",
            'csrf_token' => csrf_hash(),
        ]));
    }

    /**
     * AJAX: Jumlah SKL untuk suatu tahun (tampilan di card hapus)
     */
    public function getSklCountByYearAjax(int $academicYearId)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $count = $this->graduationService->getSklCountByYear($academicYearId);

        return $this->response->setJSON([
            'success' => true,
            'count'   => $count,
            'year_id' => $academicYearId,
        ]);
    }

    public function getSklStudentListAjax()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activeYear = $this->academicYearModel->getActive();
        if (!$activeYear) {
            return $this->response->setJSON(['success' => false, 'message' => 'Tidak ada Tahun Ajaran aktif.', 'students' => []]);
        }

        $settings = $this->graduationSettingModel->getSettingsByYear($activeYear['id']);
        if (!$settings || empty($settings['final_grade_id'])) {
            return $this->response->setJSON(['success' => false, 'message' => 'Harap tentukan kelas akhir di Pengaturan Kelulusan terlebih dahulu.', 'students' => []]);
        }

        $students = $this->graduationService->getSklStudentList($activeYear['id'], $settings['final_grade_id']);

        return $this->response->setJSON(['success' => true, 'students' => $students]);
    }

    public function deleteSklMassal(int $academicYearId)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $year = $this->academicYearModel->find($academicYearId);
        if (!$year) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Tahun Ajaran tidak ditemukan.',
                'csrf_token' => csrf_hash(),
            ]);
        }

        if ($this->graduationService->deleteSklMassal($academicYearId)) {
            return $this->response->setJSON([
                'success' => true,
                'message' => 'Semua SKL untuk tahun ajaran ini berhasil dihapus.',
                'csrf_token' => csrf_hash(),
            ]);
        } else {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Gagal menghapus SKL.',
                'csrf_token' => csrf_hash(),
            ]);
        }
    }
}
