<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\StudentModel;
use App\Models\ClassroomModel;
use App\Models\AcademicPeriodModel;
use App\Models\StudentAcademicHistoryModel;
use App\Models\SchoolSettingModel;

class BukuInduk extends BaseController
{
    protected $studentModel;
    protected $classroomModel;
    protected $periodModel;
    protected $historyModel;
    protected $settingModel;

    public function __construct()
    {
        $this->studentModel   = new StudentModel();
        $this->classroomModel = new ClassroomModel();
        $this->periodModel    = new AcademicPeriodModel();
        $this->historyModel   = new StudentAcademicHistoryModel();
        $this->settingModel   = new SchoolSettingModel();
    }

    private function checkAccess()
    {
        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', 'Anda tidak memiliki hak akses.');
        }

        return null;
    }

    /**
     * Halaman Utama: Daftar Kelas & Siswa (Pencarian Kata Kunci)
     */
    public function index()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $keyword = $this->request->getGet('q');

        $activePeriod = $this->periodModel->getActive();
        $activePeriodId = $activePeriod ? $activePeriod['id'] : null;

        $students = [];
        if (!empty($keyword)) {
            $builder = $this->studentModel->select('
                    students.*,
                    classrooms.name as classroom_name
                ')
                ->join('student_academic_histories sah', 'sah.student_id = students.id AND sah.academic_period_id = ' . ($activePeriodId ? (int)$activePeriodId : 0), 'left')
                ->join('classrooms', 'classrooms.id = sah.classroom_id', 'left')
                ->groupStart()
                    ->like('students.nis', $keyword)
                    ->orLike('students.nisn', $keyword)
                    ->orLike('students.full_name', $keyword)
                ->groupEnd()
                ->where('students.deleted_at', null)
                ->orderBy('students.full_name', 'ASC');

            $students = $builder->findAll();
        }

        $data = [
            'title'    => 'Buku Induk Siswa',
            'keyword'  => $keyword,
            'students' => $students
        ];

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

    /**
     * Detail Buku Induk Siswa
     */
    public function view($studentId)
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $student = $this->studentModel->find($studentId);
        if (!$student) {
            return redirect()->to('/buku-induk')->with('error', 'Data siswa tidak ditemukan.');
        }

        // Format Tempat & Tanggal Lahir Siswa
        $student['birth_place'] = ucwords(strtolower(trim($student['birth_place'] ?? '')));
        $student['birth_date']  = $this->formatIndonesianDate($student['birth_date'] ?? '');

        // Format data orang tua jika ada
        if (!empty($student['father_birth_place'])) {
            $student['father_birth_place'] = ucwords(strtolower(trim($student['father_birth_place'])));
        }
        if (!empty($student['mother_birth_place'])) {
            $student['mother_birth_place'] = ucwords(strtolower(trim($student['mother_birth_place'])));
        }

        $academicData = $this->getStudentAcademicAndGrades($studentId);

        $data = array_merge([
            'title'    => 'Buku Induk - ' . esc($student['full_name']),
            'student'  => $student,
            'settings' => $this->settingModel->getSettings(),
        ], $academicData);

        return view('buku_induk/view', $data);
    }

    /**
     * Print Lembar Buku Induk
     */
    public function print($studentId)
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $student = $this->studentModel->find($studentId);
        if (!$student) {
            return 'Data siswa tidak ditemukan.';
        }

        // Format Tempat & Tanggal Lahir Siswa
        $student['birth_place'] = ucwords(strtolower(trim($student['birth_place'] ?? '')));
        $student['birth_date']  = $this->formatIndonesianDate($student['birth_date'] ?? '');

        // Format data orang tua jika ada
        if (!empty($student['father_birth_place'])) {
            $student['father_birth_place'] = ucwords(strtolower(trim($student['father_birth_place'])));
        }
        if (!empty($student['mother_birth_place'])) {
            $student['mother_birth_place'] = ucwords(strtolower(trim($student['mother_birth_place'])));
        }

        $academicData = $this->getStudentAcademicAndGrades($studentId);

        $data = array_merge([
            'student'  => $student,
            'settings' => $this->settingModel->getSettings(),
        ], $academicData);

        return view('buku_induk/print', $data);
    }

    /**
     * Helper: Format Tanggal ke Bahasa Indonesia
     */
    private function formatIndonesianDate($dateString): string
    {
        if (empty($dateString)) return '-';
        $timestamp = strtotime($dateString);
        if (!$timestamp) return '-';

        $months = [
            1 => 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
            'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'
        ];

        $day = date('j', $timestamp);
        $monthNum = (int)date('n', $timestamp);
        $year = date('Y', $timestamp);

        return $day . ' ' . $months[$monthNum] . ' ' . $year;
    }

    /**
     * Helper: Ambil riwayat kelas dan rekap nilai per semester
     */
    private function getStudentAcademicAndGrades($studentId): array
    {
        // 1. Ambil riwayat rombel
        $histories = $this->historyModel->getByStudent($studentId);

        // Urutkan kronologis dari tahun terlama ke terbaru
        usort($histories, function($a, $b) {
            $yearA = (int) explode('/', $a['year_name'])[0];
            $yearB = (int) explode('/', $b['year_name'])[0];
            if ($yearA !== $yearB) return $yearA - $yearB;
            return (int)$a['semester'] - (int)$b['semester'];
        });

        // Petakan periodId ke Semester index 1 - 6
        $periodSemesterMap = [];
        $gradeNamesBySemesterGroup = [];
        $semesterIndex = 1;
        foreach ($histories as $h) {
            $periodSemesterMap[$h['academic_period_id']] = $semesterIndex;
            $groupIndex = ceil($semesterIndex / 2);
            if (!isset($gradeNamesBySemesterGroup[$groupIndex])) {
                $gradeNamesBySemesterGroup[$groupIndex] = $h['grade_name'];
            }
            $semesterIndex++;
        }

        // Tentukan Header Tingkat Kelas Dinamis (Semester 1-2 -> g1, Sem 3-4 -> g2, Sem 5-6 -> g3)
        $gradeHeader1 = $gradeNamesBySemesterGroup[1] ?? '';
        $gradeHeader2 = $gradeNamesBySemesterGroup[2] ?? '';
        $gradeHeader3 = $gradeNamesBySemesterGroup[3] ?? '';

        // Deteksi dan fallback jika data history masih belum lengkap/siswa baru
        if (empty($gradeHeader1)) {
            $db = \Config\Database::connect();
            $allGrades = $db->table('grades')->orderBy('order', 'ASC')->get()->getResultArray();
            $gradeNames = array_column($allGrades, 'name');
            $gradeHeader1 = $gradeNames[0] ?? 'Tingkat 1';
            $gradeHeader2 = $gradeNames[1] ?? 'Tingkat 2';
            $gradeHeader3 = $gradeNames[2] ?? 'Tingkat 3';
        } else {
            // Prediksi tingkatan kelas berikutnya jika belum ditempuh oleh siswa
            if (empty($gradeHeader2) || empty($gradeHeader3)) {
                $g1 = strtoupper(trim($gradeHeader1));
                if ($g1 === 'VII' || $g1 === '7') {
                    $gradeHeader2 = ($g1 === 'VII') ? 'VIII' : '8';
                    $gradeHeader3 = ($g1 === 'VII') ? 'IX' : '9';
                } elseif ($g1 === 'X' || $g1 === '10') {
                    $gradeHeader2 = ($g1 === 'X') ? 'XI' : '11';
                    $gradeHeader3 = ($g1 === 'X') ? 'XII' : '12';
                } elseif ($g1 === 'I' || $g1 === '1') {
                    $gradeHeader2 = ($g1 === 'I') ? 'II' : '2';
                    $gradeHeader3 = ($g1 === 'I') ? 'III' : '3';
                } else {
                    $db = \Config\Database::connect();
                    $allGrades = $db->table('grades')->orderBy('order', 'ASC')->get()->getResultArray();
                    $gradeNames = array_column($allGrades, 'name');
                    $gradeHeader1 = $gradeNames[0] ?? 'Tingkat 1';
                    $gradeHeader2 = $gradeNames[1] ?? 'Tingkat 2';
                    $gradeHeader3 = $gradeNames[2] ?? 'Tingkat 3';
                }
            }
        }

        // 2. Ambil seluruh data nilai legger siswa
        $db = \Config\Database::connect();
        $gradesRaw = $db->table('student_grades sg')
            ->select('sg.academic_period_id, sg.school_subject_id, sg.score, 
                      ss.name as subject_name, ss.code as subject_code, ss.sort_order,
                      s.group as subject_group')
            ->join('school_subjects ss', 'ss.id = sg.school_subject_id')
            ->join('subjects s', 's.id = ss.subject_id', 'left')
            ->where('sg.student_id', $studentId)
            ->get()->getResultArray();

        // Susun daftar pelajaran & sebaran nilai semester 1-6 dikelompokkan berdasarkan subject_group
        $subjects = [];
        foreach ($gradesRaw as $g) {
            $subId = $g['school_subject_id'];
            $groupName = trim($g['subject_group'] ?? '');
            if (empty($groupName)) {
                $groupName = 'Muatan Lokal'; // fallback untuk mapel kustom/mandiri yang diinput sekolah
            }

            // Ubah istilah kelompok 'Tambahan' menjadi 'Muatan Lokal' agar lebih formal
            if (strcasecmp($groupName, 'Tambahan') === 0) {
                $groupName = 'Muatan Lokal';
            }

            if (!isset($subjects[$groupName][$subId])) {
                $subjects[$groupName][$subId] = [
                    'id'         => $subId,
                    'name'       => $g['subject_name'],
                    'code'       => $g['subject_code'],
                    'sort_order' => $g['sort_order'],
                    'semesters'  => array_fill(1, 6, '-'), // init sem 1-6 dengan strip
                ];
            }

            $periodId = $g['academic_period_id'];
            if (isset($periodSemesterMap[$periodId])) {
                $semNum = $periodSemesterMap[$periodId];
                if ($semNum >= 1 && $semNum <= 6) {
                    $subjects[$groupName][$subId]['semesters'][$semNum] = $g['score'];
                }
            }
        }

        // Urutkan pelajaran per grup berdasarkan sort_order database
        foreach ($subjects as $groupName => &$groupSubs) {
            usort($groupSubs, fn($a, $b) => (int)$a['sort_order'] - (int)$b['sort_order']);
        }
        
        // Urutkan grup secara kustom (Keagamaan -> Umum -> Pilihan -> Muatan Lokal)
        $priorityOrder = [
            'Keagamaan'            => 1,
            'Umum'                 => 2,
            'Pilihan'              => 3,
            'Pilihan IPA'          => 4,
            'Pilihan IPS'          => 5,
            'Pilihan Lintas Minat' => 6,
            'Muatan Lokal'         => 7,
        ];

        uksort($subjects, function($a, $b) use ($priorityOrder) {
            $orderA = $priorityOrder[$a] ?? 99;
            $orderB = $priorityOrder[$b] ?? 99;
            return $orderA - $orderB;
        });

        return [
            'histories'    => $histories,
            'subjects'     => $subjects,
            'gradeHeader1' => $gradeHeader1,
            'gradeHeader2' => $gradeHeader2,
            'gradeHeader3' => $gradeHeader3,
        ];
    }
}
