<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\AssessmentModel;
use App\Models\AssessmentTypeModel;
use App\Models\AssessmentClassSettingModel;
use App\Models\AcademicPeriodModel;
use App\Models\SchoolSubjectModel;
use App\Models\ClassroomModel;
use App\Models\TeacherModel;
use App\Models\GradeModel;

class Assessment extends BaseController
{
    protected $assessmentModel;
    protected $assessmentTypeModel;
    protected $assessmentClassSettingModel;
    protected $periodModel;
    protected $subjectModel;
    protected $classroomModel;
    protected $teacherModel;
    protected $gradeModel;

    public function __construct()
    {
        $this->assessmentModel             = new AssessmentModel();
        $this->assessmentTypeModel         = new AssessmentTypeModel();
        $this->assessmentClassSettingModel = new AssessmentClassSettingModel();
        $this->periodModel                 = new AcademicPeriodModel();
        $this->subjectModel                = new SchoolSubjectModel();
        $this->classroomModel              = new ClassroomModel();
        $this->teacherModel                = new TeacherModel();
        $this->gradeModel                  = new GradeModel();
    }

    // -------------------------------------------------------
    // Helper: cek login & role admin
    // -------------------------------------------------------
    private function checkLogin()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }
        $role = session()->get('user_role');
        if (!in_array($role, ['superadmin', 'admin'])) {
            return redirect()->to('/dashboard')->with('error', 'Akses ditolak!');
        }
        return null;
    }

    // -------------------------------------------------------
    // Daftar semua event asesmen
    // -------------------------------------------------------
    public function index()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activePeriod = $this->periodModel->getActive();
        $periods      = $this->periodModel->getAllWithYear();

        $selectedPeriodId = $this->request->getGet('academic_period_id')
            ?: ($activePeriod['id'] ?? ($periods[0]['id'] ?? null));

        $data = [
            'title'            => 'Manajemen Asesmen',
            'assessments'      => $this->assessmentModel->getAllAssessments($selectedPeriodId),
            'periods'          => $periods,
            'selectedPeriodId' => $selectedPeriodId,
        ];

        return view('assessment/index', $data);
    }

    // -------------------------------------------------------
    // Form buat event asesmen baru (ASTS / ASAS / ASAT)
    // ASH dibuat dari sisi guru, bukan admin
    // -------------------------------------------------------
    public function create()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activePeriod = $this->periodModel->getActive();

        if (!$activePeriod) {
            return redirect()->to('/assessment')
                ->with('error', 'Belum ada periode akademik aktif!');
        }

        // Hanya tampilkan tipe yang dibuat admin (ASTS, ASAS, ASAT) — created_by = 1
        $assessmentTypes = $this->assessmentTypeModel
            ->where('created_by', 1)
            ->where('is_active', 1)
            ->findAll();

        $data = [
            'title'           => 'Buat Event Asesmen',
            'activePeriod'    => $activePeriod,
            'periods'         => $this->periodModel->getAllWithYear(),
            'assessmentTypes' => $assessmentTypes,
        ];

        return view('assessment/create', $data);
    }

    // -------------------------------------------------------
    // Simpan event asesmen baru (ASTS / ASAS / ASAT)
    // -------------------------------------------------------
    public function store()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $rules = [
            'assessment_type_id' => 'required|integer',
            'name'               => 'required|max_length[100]',
            'academic_period_id' => 'required|integer',
            'start_date'         => 'required|valid_date',
            'end_date'           => 'required|valid_date',
            // Minimal 1 jenis soal harus dipilih — validasi manual di bawah
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()
                ->with('errors', $this->validator->getErrors())
                ->withInput();
        }

        // Validasi: minimal 1 jenis soal dipilih
        $hasPg    = $this->request->getPost('has_pg')    ? 1 : 0;
        $hasBs    = $this->request->getPost('has_bs')    ? 1 : 0;
        $hasIsian = $this->request->getPost('has_isian') ? 1 : 0;
        $hasEssay = $this->request->getPost('has_essay') ? 1 : 0;

        if (!$hasPg && !$hasBs && !$hasIsian && !$hasEssay) {
            return redirect()->back()
                ->with('error', 'Pilih minimal 1 jenis soal!')
                ->withInput();
        }

        // Validasi: kalau isian/essay mode per_nomor, jumlah soal harus diisi
        $isianMode       = $this->request->getPost('isian_mode') ?? 'total';
        $isianTotalSoal  = (int) ($this->request->getPost('isian_total_soal') ?? 0);
        $essayMode       = $this->request->getPost('essay_mode') ?? 'total';
        $essayTotalSoal  = (int) ($this->request->getPost('essay_total_soal') ?? 0);

        if ($hasIsian && $isianMode === 'per_nomor' && $isianTotalSoal < 1) {
            return redirect()->back()
                ->with('error', 'Jumlah soal isian harus diisi jika mode per nomor!')
                ->withInput();
        }

        if ($hasEssay && $essayMode === 'per_nomor' && $essayTotalSoal < 1) {
            return redirect()->back()
                ->with('error', 'Jumlah soal essay harus diisi jika mode per nomor!')
                ->withInput();
        }

        $bobotByAdmin = $this->request->getPost('bobot_by_admin') ? 1 : 0;
        $adminBobotPg    = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_pg')    ?? 0) : 0;
        $adminBobotBs    = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_bs')    ?? 0) : 0;
        $adminBobotIsian = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_isian') ?? 0) : 0;
        $adminBobotEssay = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_essay') ?? 0) : 0;

        // Validasi total bobot jika admin-controlled
        if ($bobotByAdmin) {
            $totalBobot = $adminBobotPg + $adminBobotBs + $adminBobotIsian + $adminBobotEssay;
            if ($totalBobot !== 100) {
                return redirect()->back()
                    ->with('error', 'Total bobot harus 100% (saat ini: ' . $totalBobot . '%) jika bobot diatur admin!')
                    ->withInput();
            }
        }

        $data = [
            'assessment_type_id' => $this->request->getPost('assessment_type_id'),
            'name'               => $this->request->getPost('name'),
            'description'        => $this->request->getPost('description'),
            'academic_period_id' => $this->request->getPost('academic_period_id'),
            'start_date'         => $this->request->getPost('start_date'),
            'end_date'           => $this->request->getPost('end_date'),
            'is_open'            => 1,
            'is_visible'         => 1,
            'created_by'         => session()->get('user_id'),
            // Jenis soal
            'has_pg'             => $hasPg,
            'has_bs'             => $hasBs,
            'has_isian'          => $hasIsian,
            'has_essay'          => $hasEssay,
            // Mode isian
            'isian_mode'         => $hasIsian ? $isianMode : 'total',
            'isian_total_soal'   => $hasIsian ? $isianTotalSoal : 0,
            // Mode essay
            'essay_mode'         => $hasEssay ? $essayMode : 'total',
            'essay_total_soal'   => $hasEssay ? $essayTotalSoal : 0,
            // Bobot admin-controlled
            'bobot_by_admin'     => $bobotByAdmin,
            'admin_bobot_pg'     => $adminBobotPg,
            'admin_bobot_bs'     => $adminBobotBs,
            'admin_bobot_isian'  => $adminBobotIsian,
            'admin_bobot_essay'  => $adminBobotEssay,
            // ASTS/ASAS/ASAT berlaku semua kelas — tidak perlu set classroom/subject/grade di sini
            'grade_id'           => null,
            'subject_id'         => null,
            'classroom_id'       => null,
            'teacher_id'         => null,
        ];

        $this->assessmentModel->insert($data);

        return redirect()->to('/assessment')
            ->with('success', 'Event asesmen berhasil dibuat!');
    }

    // -------------------------------------------------------
    // Hapus event asesmen (soft delete)
    // Proteksi: ASH tidak boleh dihapus oleh admin
    // -------------------------------------------------------
    public function delete($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $assessment = $this->assessmentModel
            ->select('assessments.*, at.code as assessment_type_code')
            ->join('assessment_types at', 'at.id = assessments.assessment_type_id')
            ->where('assessments.id', $id)
            ->first();

        if (!$assessment) {
            return redirect()->to('/assessment')->with('error', 'Asesmen tidak ditemukan!');
        }

        if ($assessment['assessment_type_code'] === 'ASH') {
            return redirect()->to('/assessment')->with('error', 'ASH hanya bisa dihapus oleh guru yang bersangkutan!');
        }

        $this->assessmentModel->delete($id);

        return redirect()->to('/assessment')
            ->with('success', 'Event asesmen berhasil dihapus!');
    }

    // -------------------------------------------------------
    // Form edit event asesmen
    // Proteksi: ASH tidak boleh diedit oleh admin
    // -------------------------------------------------------
    public function edit($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $assessment = $this->assessmentModel
            ->select('assessments.*, at.name as assessment_type_name, at.code as assessment_type_code')
            ->join('assessment_types at', 'at.id = assessments.assessment_type_id')
            ->where('assessments.id', $id)
            ->first();

        if (!$assessment) {
            return redirect()->to('/assessment')->with('error', 'Asesmen tidak ditemukan!');
        }

        if ($assessment['assessment_type_code'] === 'ASH') {
            return redirect()->to('/assessment')->with('error', 'ASH hanya bisa diedit oleh guru yang bersangkutan!');
        }

        $data = [
            'title'      => 'Edit Event Asesmen',
            'assessment' => $assessment,
            'periods'    => $this->periodModel->getAllWithYear(),
        ];

        return view('assessment/edit', $data);
    }

    // -------------------------------------------------------
    // Simpan perubahan event asesmen
    // -------------------------------------------------------
    public function update($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $assessment = $this->assessmentModel->find($id);
        if (!$assessment) {
            return redirect()->to('/assessment')->with('error', 'Asesmen tidak ditemukan!');
        }

        $rules = [
            'name'               => 'required|max_length[100]',
            'academic_period_id' => 'required|integer',
            'start_date'         => 'required|valid_date',
            'end_date'           => 'required|valid_date',
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()
                ->with('errors', $this->validator->getErrors())
                ->withInput();
        }

        $hasPg    = $this->request->getPost('has_pg')    ? 1 : 0;
        $hasBs    = $this->request->getPost('has_bs')    ? 1 : 0;
        $hasIsian = $this->request->getPost('has_isian') ? 1 : 0;
        $hasEssay = $this->request->getPost('has_essay') ? 1 : 0;

        if (!$hasPg && !$hasBs && !$hasIsian && !$hasEssay) {
            return redirect()->back()
                ->with('error', 'Pilih minimal 1 jenis soal!')
                ->withInput();
        }

        $isianMode      = $this->request->getPost('isian_mode') ?? 'total';
        $isianTotalSoal = (int) ($this->request->getPost('isian_total_soal') ?? 0);
        $essayMode      = $this->request->getPost('essay_mode') ?? 'total';
        $essayTotalSoal = (int) ($this->request->getPost('essay_total_soal') ?? 0);

        $bobotByAdmin = $this->request->getPost('bobot_by_admin') ? 1 : 0;
        $adminBobotPg    = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_pg')    ?? 0) : 0;
        $adminBobotBs    = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_bs')    ?? 0) : 0;
        $adminBobotIsian = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_isian') ?? 0) : 0;
        $adminBobotEssay = $bobotByAdmin ? (int)($this->request->getPost('admin_bobot_essay') ?? 0) : 0;

        if ($bobotByAdmin) {
            $totalBobot = $adminBobotPg + $adminBobotBs + $adminBobotIsian + $adminBobotEssay;
            if ($totalBobot !== 100) {
                return redirect()->back()
                    ->with('error', 'Total bobot harus 100% (saat ini: ' . $totalBobot . '%) jika bobot diatur admin!')
                    ->withInput();
            }
        }

        $this->assessmentModel->update($id, [
            'name'               => $this->request->getPost('name'),
            'description'        => $this->request->getPost('description') ?? '',
            'academic_period_id' => $this->request->getPost('academic_period_id'),
            'start_date'         => $this->request->getPost('start_date'),
            'end_date'           => $this->request->getPost('end_date'),
            'has_pg'             => $hasPg,
            'has_bs'             => $hasBs,
            'has_isian'          => $hasIsian,
            'has_essay'          => $hasEssay,
            'isian_mode'         => $hasIsian ? $isianMode : 'total',
            'isian_total_soal'   => $hasIsian ? $isianTotalSoal : 0,
            'essay_mode'         => $hasEssay ? $essayMode : 'total',
            'essay_total_soal'   => $hasEssay ? $essayTotalSoal : 0,
            'bobot_by_admin'     => $bobotByAdmin,
            'admin_bobot_pg'     => $adminBobotPg,
            'admin_bobot_bs'     => $adminBobotBs,
            'admin_bobot_isian'  => $adminBobotIsian,
            'admin_bobot_essay'  => $adminBobotEssay,
        ]);

        return redirect()->to('/assessment')
            ->with('success', 'Event asesmen berhasil diperbarui!');
    }

    // -------------------------------------------------------
    // Toggle buka/tutup event asesmen
    // -------------------------------------------------------
    public function toggleOpen($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $assessment = $this->assessmentModel->find($id);
        if (!$assessment) {
            return redirect()->to('/assessment')->with('error', 'Asesmen tidak ditemukan!');
        }

        $this->assessmentModel->update($id, [
            'is_open' => $assessment['is_open'] ? 0 : 1,
        ]);

        $status = $assessment['is_open'] ? 'ditutup' : 'dibuka';
        return redirect()->to('/assessment')
            ->with('success', "Event asesmen berhasil $status!");
    }

    // -------------------------------------------------------
    // Toggle tampil/sembunyikan event asesmen di guru
    // -------------------------------------------------------
    public function toggleVisible($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $assessment = $this->assessmentModel->find($id);
        if (!$assessment) {
            return redirect()->to('/assessment')->with('error', 'Asesmen tidak ditemukan!');
        }

        $this->assessmentModel->update($id, [
            'is_visible' => $assessment['is_visible'] ? 0 : 1,
        ]);

        $status = $assessment['is_visible'] ? 'disembunyikan dari guru' : 'ditampilkan ke guru';
        return redirect()->to('/assessment')
            ->with('success', "Event asesmen berhasil $status!");
    }

    // -------------------------------------------------------
    // AJAX: ambil kelas berdasarkan grade (untuk form ASH admin jika diperlukan)
    // -------------------------------------------------------
    public function getClassroomsByGrade()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $gradeId = $this->request->getGet('grade_id');

        if (!$gradeId) {
            return $this->response->setJSON([]);
        }

        $classrooms = $this->classroomModel
            ->select('id, name')
            ->where('grade_id', $gradeId)
            ->where('deleted_at', null)
            ->orderBy('name', 'ASC')
            ->findAll();

        return $this->response->setJSON($classrooms);
    }
}