<?php

namespace App\Controllers\Guru;

use App\Controllers\BaseController;
use App\Models\TahfidzProgramModel;
use App\Models\TahfidzSetoranModel;
use App\Models\TahfidzHafalanModel;
use App\Models\QuranSurahModel;
use App\Models\TeacherModel;
use App\Models\AcademicPeriodModel;
use App\Models\TahfidzReportModel;

class TahfidzController extends BaseController
{
    protected $programModel;
    protected $setoranModel;
    protected $hafalanModel;
    protected $surahModel;
    protected $teacherModel;
    protected $periodModel;
    protected $reportModel;

    public function __construct()
    {
        $this->programModel = new TahfidzProgramModel();
        $this->setoranModel = new TahfidzSetoranModel();
        $this->hafalanModel = new TahfidzHafalanModel();
        $this->surahModel   = new QuranSurahModel();
        $this->teacherModel = new TeacherModel();
        $this->periodModel  = new AcademicPeriodModel();
        $this->reportModel  = new TahfidzReportModel();
    }

    private function getTeacher()
    {
        $userId  = session()->get('user_id');
        $teacher = $this->teacherModel->where('user_id', $userId)->first();
        return $teacher;
    }

    private function checkAccess()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }
        if (session()->get('user_role') !== 'guru') {
            return redirect()->to('/dashboard');
        }
        return null;
    }

    // ── DASHBOARD TAHFIDZ GURU ───────────────────────────────────────
    public function index()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $teacher = $this->getTeacher();
        if (!$teacher) {
            return redirect()->to('/guru/dashboard')->with('error', 'Data guru tidak ditemukan.');
        }

        $activePeriod = $this->periodModel->getActive();
        if (!$activePeriod) {
            return view('guru/tahfidz/index', [
                'title'    => 'Tahfidz Al-Qur\'an',
                'teacher'  => $teacher,
                'programs' => [],
                'activePeriod' => null,
            ]);
        }

        $programs = $this->programModel->getByTeacher($teacher['id'], $activePeriod['id']);

        // Deteksi program terpilih dari query param
        $selectedProgramId = $this->request->getGet('program_id');
        $selectedProgram = null;
        if ($selectedProgramId) {
            foreach ($programs as $p) {
                if ($p['id'] == $selectedProgramId) {
                    $selectedProgram = $p;
                    break;
                }
            }
        }

        $programStats = [];
        foreach ($programs as $p) {
            $students   = $this->programModel->getStudents($p['id']);
            $todaySetor = $this->setoranModel->getTodayByProgram($p['id']);
            $blumSetor  = $this->setoranModel->getSiswaBlumSetor($p['id'], 7);

            $programStats[] = [
                'program'        => $p,
                'total_students' => count($students),
                'today_setoran'  => count($todaySetor),
                'blum_setor_7d'  => count($blumSetor),
            ];
        }

        $data = [
            'title'        => 'Tahfidz Al-Qur\'an',
            'teacher'      => $teacher,
            'activePeriod' => $activePeriod,
            'programs'     => $programs,
            'programStats' => $programStats,
            'selectedProgram' => $selectedProgram,
        ];

        // Jika program terpilih, muat data detail program
        if ($selectedProgram) {
            $data['students']     = $this->programModel->getStudents($selectedProgram['id']);
            $data['todaySetor']   = $this->setoranModel->getTodayByProgram($selectedProgram['id']);
            $data['blumSetor']    = $this->setoranModel->getSiswaBlumSetor($selectedProgram['id'], 7);
            $data['rekapHafalan'] = $this->hafalanModel->getRekapByProgram($selectedProgram['id']);
        }

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

    // ── INPUT SETORAN ────────────────────────────────────────────────
    public function setoran($programId = null)
    {
        if ($redirect = $this->checkAccess()) return $redirect;

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

        if (!$teacher || !$activePeriod) {
            return redirect()->to('/guru/tahfidz')->with('error', 'Data tidak lengkap.');
        }

        $programs = $this->programModel->getByTeacher($teacher['id'], $activePeriod['id']);
        if (empty($programs)) {
            return redirect()->to('/guru/tahfidz')->with('error', 'Anda belum ditugaskan ke program tahfidz manapun.');
        }

        // Tentukan program aktif (dari URL/query param atau default pertama)
        $selectedProgram = null;
        $progId = $programId ?: $this->request->getGet('program_id');
        if ($progId) {
            foreach ($programs as $p) {
                if ($p['id'] == $progId) {
                    $selectedProgram = $p;
                    break;
                }
            }
        }
        if (!$selectedProgram) {
            $selectedProgram = $programs[0];
        }

        $students     = $this->programModel->getStudents($selectedProgram['id']);
        $surahs       = $this->surahModel->orderBy('number', 'ASC')->findAll();
        $todaySetorans= $this->setoranModel->getTodayByProgram($selectedProgram['id']);

        // Ambil siswa tertentu jika ada param
        $selectedStudentId = (int) $this->request->getGet('student_id');

        return view('guru/tahfidz/setoran', [
            'title'             => 'Input Setoran Tahfidz',
            'teacher'           => $teacher,
            'activePeriod'      => $activePeriod,
            'programs'          => $programs,
            'selectedProgram'   => $selectedProgram,
            'students'          => $students,
            'surahs'            => $surahs,
            'todaySetorans'     => $todaySetorans,
            'selectedStudentId' => $selectedStudentId,
        ]);
    }

    public function storeSetoran()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $teacher = $this->getTeacher();
        if (!$teacher) {
            return $this->response->setJSON(['success' => false, 'message' => 'Data guru tidak ditemukan.']);
        }

        $programId  = (int) $this->request->getPost('program_id');
        $studentId  = (int) $this->request->getPost('student_id');
        $surahId    = (int) $this->request->getPost('surah_id');
        $ayatStart  = (int) $this->request->getPost('ayat_start');
        $ayatEnd    = (int) $this->request->getPost('ayat_end');
        $isIqra     = (int) $this->request->getPost('is_iqra') === 1;
        $iqraNo     = (int) $this->request->getPost('iqra_no');
        $iqraPageStart = (int) $this->request->getPost('iqra_page_start');
        $iqraPageEnd   = (int) $this->request->getPost('iqra_page_end');
        $jenis      = $this->request->getPost('jenis') === 'murajaah' ? 'murajaah' : 'ziyadah';
        $nilai      = min(100, max(0, (int) $this->request->getPost('nilai')));
        $catatan    = $this->request->getPost('catatan');
        $tanggal    = $this->request->getPost('setoran_date') ?: date('Y-m-d');

        // Pastikan guru memang pengampu program ini
        $programs = $this->programModel->getByTeacher($teacher['id']);
        $programIds = array_column($programs, 'id');
        if (!in_array($programId, $programIds)) {
            return $this->response->setJSON(['success' => false, 'message' => 'Akses ditolak.']);
        }

        if ($isIqra) {
            // Validasi Iqra
            if (!$programId || !$studentId || $iqraNo < 1 || $iqraNo > 6 || $iqraPageStart < 1 || $iqraPageEnd < $iqraPageStart) {
                return $this->response->setJSON(['success' => false, 'message' => 'Data Iqra tidak lengkap atau tidak valid.']);
            }

            $insertData = [
                'program_id'      => $programId,
                'student_id'      => $studentId,
                'teacher_id'      => $teacher['id'],
                'surah_id'        => null,
                'ayat_start'      => null,
                'ayat_end'        => null,
                'is_iqra'         => 1,
                'iqra_no'         => $iqraNo,
                'iqra_page_start' => $iqraPageStart,
                'iqra_page_end'   => $iqraPageEnd,
                'jenis'           => $jenis,
                'nilai'           => $nilai,
                'catatan'         => $catatan,
                'setoran_date'    => $tanggal,
            ];
        } else {
            // Validasi Al-Quran
            if (!$programId || !$studentId || !$surahId || $ayatStart < 1 || $ayatEnd < $ayatStart) {
                return $this->response->setJSON(['success' => false, 'message' => 'Data Al-Qur\'an tidak lengkap atau tidak valid.']);
            }

            // Validasi jumlah ayat surah
            $surah = $this->surahModel->find($surahId);
            if (!$surah || $ayatEnd > $surah['total_ayat']) {
                return $this->response->setJSON(['success' => false, 'message' => 'Nomor ayat melebihi total ayat surah.']);
            }

            $insertData = [
                'program_id'      => $programId,
                'student_id'      => $studentId,
                'teacher_id'      => $teacher['id'],
                'surah_id'        => $surahId,
                'ayat_start'      => $ayatStart,
                'ayat_end'     => $ayatEnd,
                'is_iqra'         => 0,
                'iqra_no'         => null,
                'iqra_page_start' => null,
                'iqra_page_end'   => null,
                'jenis'           => $jenis,
                'nilai'           => $nilai,
                'catatan'         => $catatan,
                'setoran_date'    => $tanggal,
            ];
        }

        $this->setoranModel->insert($insertData);

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

    public function deleteSetoran($setoranId)
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $teacher  = $this->getTeacher();
        $setoran  = $this->setoranModel->find($setoranId);

        if (!$setoran || $setoran['teacher_id'] != $teacher['id']) {
            return $this->response->setJSON(['success' => false, 'message' => 'Tidak ditemukan atau akses ditolak.']);
        }

        $this->setoranModel->delete($setoranId);
        return $this->response->setJSON(['success' => true, 'message' => 'Setoran berhasil dihapus.']);
    }

    // ── CEKLIS HAFALAN (GRID 114 SURAH) ─────────────────────────────
    public function hafalan($programId = null)
    {
        if ($redirect = $this->checkAccess()) return $redirect;

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

        if (!$teacher || !$activePeriod) {
            return redirect()->to('/guru/tahfidz');
        }

        $programs = $this->programModel->getByTeacher($teacher['id'], $activePeriod['id']);
        if (empty($programs)) {
            return redirect()->to('/guru/tahfidz');
        }

        // Program aktif
        $selectedProgram = null;
        $progId = $programId ?: $this->request->getGet('program_id');
        if ($progId) {
            foreach ($programs as $p) {
                if ($p['id'] == $progId) { $selectedProgram = $p; break; }
            }
        }
        if (!$selectedProgram) $selectedProgram = $programs[0];

        $students          = $this->programModel->getStudents($selectedProgram['id']);
        $selectedStudentId = (int) $this->request->getGet('student_id');
        if (!$selectedStudentId && !empty($students)) {
            $selectedStudentId = $students[0]['id'];
        }

        $surahs         = $this->surahModel->orderBy('number', 'ASC')->findAll();
        $hafalanMap     = $this->hafalanModel->getByStudentProgram($selectedStudentId, $selectedProgram['id']);
        $totalHafal     = count(array_filter($hafalanMap, fn($h) => $h['is_hafal']));

        // Kelompokkan surah per juz untuk tampilan
        $surahsByJuz = [];
        foreach ($surahs as $s) {
            $surahsByJuz[$s['juz_start']][] = $s;
        }

        return view('guru/tahfidz/hafalan', [
            'title'             => 'Ceklis Hafalan',
            'teacher'           => $teacher,
            'activePeriod'      => $activePeriod,
            'programs'          => $programs,
            'selectedProgram'   => $selectedProgram,
            'students'          => $students,
            'selectedStudentId' => $selectedStudentId,
            'surahsByJuz'       => $surahsByJuz,
            'hafalanMap'        => $hafalanMap,
            'totalHafal'        => $totalHafal,
        ]);
    }

    public function saveHafalan()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $teacher   = $this->getTeacher();
        $programId = (int) $this->request->getPost('program_id');
        $studentId = (int) $this->request->getPost('student_id');
        $hafalIds  = $this->request->getPost('hafal_surah_ids') ?? [];

        if (!$teacher || !$programId || !$studentId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Data tidak lengkap.']);
        }

        // Pastikan guru mengampu program ini
        $programs   = $this->programModel->getByTeacher($teacher['id']);
        $programIds = array_column($programs, 'id');
        if (!in_array($programId, $programIds)) {
            return $this->response->setJSON(['success' => false, 'message' => 'Akses ditolak.']);
        }

        $hafalIds = array_map('intval', (array) $hafalIds);
        $this->hafalanModel->saveBulk($studentId, $programId, $teacher['id'], $hafalIds);

        $totalHafal = $this->hafalanModel->countHafal($studentId, $programId);

        return $this->response->setJSON([
            'success'    => true,
            'message'    => 'Data hafalan berhasil disimpan.',
            'total_hafal'=> $totalHafal,
        ]);
    }

    // ── PROGRESS PER JUZ ─────────────────────────────────────────────
    public function progress($programId = null)
    {
        if ($redirect = $this->checkAccess()) return $redirect;

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

        if (!$teacher || !$activePeriod) {
            return redirect()->to('/guru/tahfidz');
        }

        $programs = $this->programModel->getByTeacher($teacher['id'], $activePeriod['id']);
        if (empty($programs)) {
            return redirect()->to('/guru/tahfidz');
        }

        $selectedProgram = null;
        $progId = $programId ?: $this->request->getGet('program_id');
        if ($progId) {
            foreach ($programs as $p) {
                if ($p['id'] == $progId) { $selectedProgram = $p; break; }
            }
        }
        if (!$selectedProgram) $selectedProgram = $programs[0];

        $students          = $this->programModel->getStudents($selectedProgram['id']);
        $selectedStudentId = (int) $this->request->getGet('student_id');
        if (!$selectedStudentId && !empty($students)) {
            $selectedStudentId = $students[0]['id'];
        }

        $progressJuz  = $this->hafalanModel->getProgressPerJuz($selectedStudentId, $selectedProgram['id']);
        $totalHafal   = $this->hafalanModel->countHafal($selectedStudentId, $selectedProgram['id']);
        $avgNilai     = $this->setoranModel->getAvgNilai($selectedStudentId, $selectedProgram['id']);
        $recentSetoran= $this->setoranModel->getByStudentProgram($selectedStudentId, $selectedProgram['id']);

        return view('guru/tahfidz/progress', [
            'title'             => 'Progress Tahfidz',
            'teacher'           => $teacher,
            'activePeriod'      => $activePeriod,
            'programs'          => $programs,
            'selectedProgram'   => $selectedProgram,
            'students'          => $students,
            'selectedStudentId' => $selectedStudentId,
            'progressJuz'       => $progressJuz,
            'totalHafal'        => $totalHafal,
            'avgNilai'          => $avgNilai,
            'recentSetoran'     => array_slice($recentSetoran, 0, 10),
        ]);
    }

    // ── LAPORAN ──────────────────────────────────────────────────────
    public function laporan($programId = null)
    {
        if ($redirect = $this->checkAccess()) return $redirect;

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

        if (!$teacher || !$activePeriod) {
            return redirect()->to('/guru/tahfidz');
        }

        $programs = $this->programModel->getByTeacher($teacher['id'], $activePeriod['id']);
        if (empty($programs)) {
            return redirect()->to('/guru/tahfidz');
        }

        $selectedProgram = null;
        $progId = $programId ?: $this->request->getGet('program_id');
        if ($progId) {
            foreach ($programs as $p) {
                if ($p['id'] == $progId) { $selectedProgram = $p; break; }
            }
        }
        if (!$selectedProgram) $selectedProgram = $programs[0];

        // Rentang tanggal (default: minggu ini)
        $startDate = $this->request->getGet('start_date') ?: date('Y-m-d', strtotime('monday this week'));
        $endDate   = $this->request->getGet('end_date')   ?: date('Y-m-d', strtotime('sunday this week'));
        $classroomId = $this->request->getGet('classroom_id') ? (int) $this->request->getGet('classroom_id') : null;

        $rekapSetoran  = $this->setoranModel->getRekapByProgram($selectedProgram['id'], $startDate, $endDate, $classroomId);
        $rekapHafalan  = $this->hafalanModel->getRekapByProgram($selectedProgram['id'], $classroomId);
        $blumSetor     = $this->setoranModel->getSiswaBlumSetor($selectedProgram['id'], 7, $classroomId);

        // Ambil daftar kelas unik dari siswa terdaftar di program ini untuk filter dropdown
        $studentsAll = $this->programModel->getStudents($selectedProgram['id']);
        $uniqueClassrooms = [];
        foreach ($studentsAll as $st) {
            if ($st['classroom_id'] && !isset($uniqueClassrooms[$st['classroom_id']])) {
                $uniqueClassrooms[$st['classroom_id']] = $st['classroom_name'];
            }
        }
        asort($uniqueClassrooms);

        // Cek Konfigurasi WA
        $db = \Config\Database::connect();
        $waRows = $db->table('settings')->whereIn('setting_key', ['wa_enabled', 'wa_sidobe_api_key', 'wa_sidobe_sender', 'wa_group_id_' . $selectedProgram['id']])->get()->getResultArray();
        $waCfg = array_column($waRows, 'setting_value', 'setting_key');
        $waConfigured = ($waCfg['wa_enabled'] ?? '0') === '1' && !empty($waCfg['wa_sidobe_api_key']);
        $waGroupId = $waCfg['wa_group_id_' . $selectedProgram['id']] ?? '';

        return view('guru/tahfidz/laporan', [
            'title'            => 'Laporan Tahfidz',
            'teacher'          => $teacher,
            'activePeriod'     => $activePeriod,
            'programs'         => $programs,
            'selectedProgram'  => $selectedProgram,
            'rekapSetoran'     => $rekapSetoran,
            'rekapHafalan'     => $rekapHafalan,
            'blumSetor'        => $blumSetor,
            'startDate'        => $startDate,
            'endDate'          => $endDate,
            'classrooms'       => $uniqueClassrooms,
            'selectedClassId'  => $classroomId,
            'waConfigured'     => $waConfigured,
            'waGroupId'        => $waGroupId,
        ]);
    }

    // ── AJAX: Get total ayat surah ────────────────────────────────────
    public function getSurahInfo($surahId)
    {
        $surah = $this->surahModel->find($surahId);
        if (!$surah) {
            return $this->response->setJSON(['success' => false]);
        }
        return $this->response->setJSON([
            'success'    => true,
            'total_ayat' => $surah['total_ayat'],
            'name_latin' => $surah['name_latin'],
            'name_arabic'=> $surah['name_arabic'],
        ]);
    }

    // ── KIRIM REKAP KE GRUP WA ───────────────────────────────────────
    public function sendWaGrup()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $wa = new \App\Services\WhatsappService();
        if (!$wa->isConfigured()) {
            return $this->response->setJSON(['success' => false, 'message' => 'Konfigurasi WhatsApp belum diatur di Pengaturan.']);
        }

        if (!$wa->isFeatureEnabled('tahfidz')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Fitur laporan Tahfidz via WhatsApp dinonaktifkan di Pengaturan.']);
        }

        $programId  = (int) $this->request->getPost('program_id');
        $groupId    = trim($this->request->getPost('group_id') ?? '');
        $startDate  = $this->request->getPost('start_date');
        $endDate    = $this->request->getPost('end_date');

        if (!$groupId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Group ID WA belum diisi.']);
        }

        $program = $this->programModel->find($programId);
        if (!$program) {
            return $this->response->setJSON(['success' => false, 'message' => 'Program tidak ditemukan.']);
        }

        $rekapSetoran = $this->setoranModel->getRekapByProgram($programId, $startDate, $endDate);

        if (empty($rekapSetoran)) {
            return $this->response->setJSON(['success' => false, 'message' => 'Tidak ada data setoran di rentang tanggal ini.']);
        }

        $db = \Config\Database::connect();
        $typeName = match($program['type']) { 'pk' => 'PK', 'boarding' => 'Boarding', default => 'KBM Pagi' };
        $lines    = [];
        foreach ($rekapSetoran as $r) {
            $avg = number_format((float)$r['rata_nilai'], 0);
            
            // Query rincian setoran untuk siswa ini
            $detailSetoran = $db->table('tahfidz_setoran ts')
                ->select('ts.is_iqra, ts.iqra_no, ts.iqra_page_start, ts.iqra_page_end, ts.ayat_start, ts.ayat_end, ts.nilai, qs.name_latin')
                ->join('quran_surahs qs', 'qs.id = ts.surah_id', 'left')
                ->where('ts.program_id', $programId)
                ->where('ts.student_id', $r['student_id'])
                ->where('ts.setoran_date >=', $startDate)
                ->where('ts.setoran_date <=', $endDate)
                ->orderBy('ts.setoran_date', 'ASC')
                ->get()->getResultArray();

            $rincianArr = [];
            foreach ($detailSetoran as $ds) {
                if ($ds['is_iqra']) {
                    $rincianArr[] = "  └ Iqra {$ds['iqra_no']} Hal. {$ds['iqra_page_start']}-{$ds['iqra_page_end']} (Nilai: {$ds['nilai']})";
                } else {
                    $rincianArr[] = "  └ {$ds['name_latin']} {$ds['ayat_start']}-{$ds['ayat_end']} (Nilai: {$ds['nilai']})";
                }
            }
            $lines[] = "• *{$r['full_name']}* (Rata: {$avg})\n" . implode("\n", $rincianArr);
        }

        $tgl   = date('d M Y', strtotime($startDate)) . ' s.d. ' . date('d M Y', strtotime($endDate));
        $pesan = "📖 *Rekap Setoran Tahfidz {$typeName}*\n";
        $pesan .= "📅 {$tgl}\n\n";
        $pesan .= implode("\n", $lines);
        $pesan .= "\n\n_Total: " . count($rekapSetoran) . " siswa_";

        $result = $wa->send($groupId, $pesan, true);
        return $this->response->setJSON($result);
    }

    // ── KIRIM LAPORAN PERSONAL KE ORTU ───────────────────────────────
    public function sendWaOrtu()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $wa = new \App\Services\WhatsappService();
        if (!$wa->isConfigured()) {
            return $this->response->setJSON(['success' => false, 'message' => 'Konfigurasi WhatsApp belum diatur di Pengaturan.']);
        }

        if (!$wa->isFeatureEnabled('tahfidz')) {
            return $this->response->setJSON(['success' => false, 'message' => 'Fitur laporan Tahfidz via WhatsApp dinonaktifkan di Pengaturan.']);
        }

        $programId = (int) $this->request->getPost('program_id');
        $startDate = $this->request->getPost('start_date');
        $endDate   = $this->request->getPost('end_date');

        $program = $this->programModel->find($programId);
        if (!$program) {
            return $this->response->setJSON(['success' => false, 'message' => 'Program tidak ditemukan.']);
        }

        $db           = \Config\Database::connect();
        $rekapSetoran = $this->setoranModel->getRekapByProgram($programId, $startDate, $endDate);

        if (empty($rekapSetoran)) {
            return $this->response->setJSON(['success' => false, 'message' => 'Tidak ada data setoran di rentang tanggal ini.']);
        }

        $typeName = match($program['type']) { 'pk' => 'PK', 'boarding' => 'Boarding', default => 'KBM Pagi' };
        $tgl      = date('d M Y', strtotime($startDate)) . ' s.d. ' . date('d M Y', strtotime($endDate));
        $sent     = 0; $skipped = 0;

        foreach ($rekapSetoran as $r) {
            // Ambil father_phone siswa
            $student = $db->table('students')->select('father_phone, full_name')->where('id', $r['student_id'])->get()->getRowArray();
            $phone   = trim($student['father_phone'] ?? '');

            if (empty($phone)) {
                $skipped++;
                continue;
            }

            $totalHafal = $this->hafalanModel->countHafal($r['student_id'], $programId);
            $avg        = number_format((float)$r['rata_nilai'], 0);

            // Query rincian setoran untuk siswa ini
            $detailSetoran = $db->table('tahfidz_setoran ts')
                ->select('ts.is_iqra, ts.iqra_no, ts.iqra_page_start, ts.iqra_page_end, ts.ayat_start, ts.ayat_end, ts.nilai, qs.name_latin')
                ->join('quran_surahs qs', 'qs.id = ts.surah_id', 'left')
                ->where('ts.program_id', $programId)
                ->where('ts.student_id', $r['student_id'])
                ->where('ts.setoran_date >=', $startDate)
                ->where('ts.setoran_date <=', $endDate)
                ->orderBy('ts.setoran_date', 'ASC')
                ->get()->getResultArray();

            $rincianArr = [];
            foreach ($detailSetoran as $ds) {
                if ($ds['is_iqra']) {
                    $rincianArr[] = "• Iqra {$ds['iqra_no']} Hal. {$ds['iqra_page_start']}-{$ds['iqra_page_end']} (Nilai: {$ds['nilai']})";
                } else {
                    $rincianArr[] = "• {$ds['name_latin']} ayat {$ds['ayat_start']}-{$ds['ayat_end']} (Nilai: {$ds['nilai']})";
                }
            }
            $rincianStr = !empty($rincianArr) ? implode("\n", $rincianArr) : "Tidak ada setoran.";
            $pesan  = "Assalamu'alaikum, Bpk/Ibu wali dari *{$r['full_name']}* 🙏\n\n";
            $pesan .= "Berikut laporan hafalan Al-Qur'an ananda:\n";
            $pesan .= "📚 Program  : Tahfidz {$typeName}\n";
            $pesan .= "📅 Periode  : {$tgl}\n\n";
            $pesan .= "✅ Total Surah Hafal : *{$totalHafal}* surah\n";
            $pesan .= "📊 Total Setoran     : *{$r['total_setoran']}x*\n";
            $pesan .= "⭐ Rerata Nilai      : *{$avg}*\n\n";
            $pesan .= "📖 *Rincian Setoran Periode Ini:*\n{$rincianStr}\n\n";
            $pesan .= "_Jazakumullahu khairan_ 🤲";

            $res = $wa->send($phone, $pesan);
            if ($res['success']) $sent++;
            else $skipped++;

            usleep(500000); // jeda 500ms
        }

        return $this->response->setJSON([
            'success' => true,
            'message' => "Laporan terkirim ke {$sent} ortu." . ($skipped > 0 ? " {$skipped} dilewati (no. WA kosong/gagal)." : ''),
        ]);
    }

    public function studentReport()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $teacher = $this->getTeacher();
        if (!$teacher) {
            return redirect()->to('/guru/dashboard')->with('error', 'Data guru tidak ditemukan.');
        }

        $programId = (int) $this->request->getGet('program_id');
        $studentId = (int) $this->request->getGet('student_id');

        $program = $this->programModel->find($programId);
        if (!$program) {
            return redirect()->back()->with('error', 'Program tidak ditemukan.');
        }

        $programs = $this->programModel->getByTeacher($teacher['id']);
        $programIds = array_column($programs, 'id');
        if (!in_array($programId, $programIds)) {
            return redirect()->back()->with('error', 'Akses ditolak.');
        }

        $student = $this->programModel->db->table('tahfidz_program_students tps')
            ->select('s.id, s.full_name, s.nis, s.nisn, c.name as classroom_name')
            ->join('students s', 's.id = tps.student_id')
            ->join('student_academic_histories sah', 'sah.student_id = s.id AND sah.academic_period_id = ' . $program['academic_period_id'], 'left')
            ->join('classrooms c', 'c.id = sah.classroom_id', 'left')
            ->where('tps.program_id', $programId)
            ->where('tps.student_id', $studentId)
            ->get()
            ->getRowArray();

        if (!$student) {
            return redirect()->back()->with('error', 'Siswa tidak ditemukan dalam program ini.');
        }

        $period = $this->periodModel->select('academic_periods.*, academic_years.name as year_name')
            ->join('academic_years', 'academic_years.id = academic_periods.academic_year_id')
            ->find($program['academic_period_id']);

        $setorans = $this->setoranModel->db->table('tahfidz_setoran ts')
            ->select('ts.*, qs.name_latin as surah_name')
            ->join('quran_surahs qs', 'qs.id = ts.surah_id', 'left')
            ->where('ts.program_id', $programId)
            ->where('ts.student_id', $studentId)
            ->orderBy('ts.setoran_date', 'ASC')
            ->get()
            ->getResultArray();

        $totalSetoran = count($setorans);
        $totalZiyadah = 0;
        $totalMurajaah = 0;
        $scores = [];
        $firstZiyadah = null;
        $lastZiyadah = null;
        $lastCatatan = '';

        foreach ($setorans as $s) {
            if ($s['jenis'] === 'ziyadah') {
                $totalZiyadah++;
                $scores[] = (int) $s['nilai'];
                if ($firstZiyadah === null) {
                    $firstZiyadah = $s;
                }
                $lastZiyadah = $s;
            } else {
                $totalMurajaah++;
            }
            if ($s['catatan'] && trim($s['catatan']) !== '') {
                $lastCatatan = $s['catatan'];
            }
        }

        $avgScore = count($scores) > 0 ? round(array_sum($scores) / count($scores), 1) : 0;
        $totalHafal = $this->hafalanModel->countHafal($studentId, $programId);

        $completedSurahs = $this->hafalanModel->db->table('tahfidz_hafalan th')
            ->select('th.surah_id, qs.name_latin as surah_name, qs.total_ayat, th.hafal_date')
            ->join('quran_surahs qs', 'qs.id = th.surah_id')
            ->where('th.student_id', $studentId)
            ->where('th.program_id', $programId)
            ->where('th.is_hafal', 1)
            ->orderBy('qs.number', 'ASC')
            ->get()
            ->getResultArray();

        foreach ($completedSurahs as &$cs) {
            $setoranAvg = $this->setoranModel->db->table('tahfidz_setoran')
                ->select('AVG(nilai) as avg_score, COUNT(id) as total_maju')
                ->where('student_id', $studentId)
                ->where('program_id', $programId)
                ->where('surah_id', $cs['surah_id'])
                ->get()
                ->getRowArray();
                
            $cs['avg_score'] = $setoranAvg['avg_score'] !== null ? round($setoranAvg['avg_score'], 1) : null;
            $cs['total_maju'] = $setoranAvg['total_maju'] ?: 0;
        }

        $report = $this->reportModel
            ->where('program_id', $programId)
            ->where('student_id', $studentId)
            ->first();

        $fashahah = $report ? $report['fashahah'] : ($avgScore ?: 0);
        $tajwid   = $report ? $report['tajwid'] : ($avgScore ?: 0);
        $adab     = $report ? $report['adab'] : ($totalSetoran > 15 ? 90 : ($totalSetoran > 8 ? 80 : 70));
        $catatan  = $report ? $report['catatan'] : $lastCatatan;

        $settingsModel = new \App\Models\SchoolSettingModel();
        $schoolSettings = $settingsModel->getSettings();

        return view('guru/tahfidz/student_report', [
            'teacher'         => $teacher,
            'program'         => $program,
            'student'         => $student,
            'period'          => $period,
            'totalSetoran'    => $totalSetoran,
            'totalZiyadah'    => $totalZiyadah,
            'totalMurajaah'   => $totalMurajaah,
            'avgScore'        => $avgScore,
            'totalHafal'      => $totalHafal,
            'completedSurahs' => $completedSurahs,
            'firstZiyadah'    => $firstZiyadah,
            'lastZiyadah'     => $lastZiyadah,
            'fashahah'        => $fashahah,
            'tajwid'          => $tajwid,
            'adab'            => $adab,
            'catatan'         => $catatan,
            'schoolSettings'  => $schoolSettings,
            'latestIqraSetoran' => array_reduce($setorans, function($carry, $item) {
                return $item['is_iqra'] ? $item : $carry;
            }, null),
        ]);
    }

    public function reportSetup()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $teacher = $this->getTeacher();
        if (!$teacher) {
            return redirect()->to('/guru/dashboard')->with('error', 'Data guru tidak ditemukan.');
        }

        $programId = (int) $this->request->getGet('program_id');
        $studentId = (int) $this->request->getGet('student_id');

        $program = $this->programModel->find($programId);
        if (!$program) {
            return redirect()->back()->with('error', 'Program tidak ditemukan.');
        }

        $programs = $this->programModel->getByTeacher($teacher['id']);
        $programIds = array_column($programs, 'id');
        if (!in_array($programId, $programIds)) {
            return redirect()->back()->with('error', 'Akses ditolak.');
        }

        $student = $this->programModel->db->table('tahfidz_program_students tps')
            ->select('s.id, s.full_name, s.nis, s.nisn, c.name as classroom_name')
            ->join('students s', 's.id = tps.student_id')
            ->join('student_academic_histories sah', 'sah.student_id = s.id AND sah.academic_period_id = ' . $program['academic_period_id'], 'left')
            ->join('classrooms c', 'c.id = sah.classroom_id', 'left')
            ->where('tps.program_id', $programId)
            ->where('tps.student_id', $studentId)
            ->get()
            ->getRowArray();

        if (!$student) {
            return redirect()->back()->with('error', 'Siswa tidak ditemukan dalam program ini.');
        }

        $period = $this->periodModel->select('academic_periods.*, academic_years.name as year_name')
            ->join('academic_years', 'academic_years.id = academic_periods.academic_year_id')
            ->find($program['academic_period_id']);

        $setorans = $this->setoranModel->db->table('tahfidz_setoran ts')
            ->select('ts.*, qs.name_latin as surah_name')
            ->join('quran_surahs qs', 'qs.id = ts.surah_id')
            ->where('ts.program_id', $programId)
            ->where('ts.student_id', $studentId)
            ->orderBy('ts.setoran_date', 'ASC')
            ->get()
            ->getResultArray();

        $totalSetoran = count($setorans);
        $scores = [];
        $lastCatatan = '';

        foreach ($setorans as $s) {
            if ($s['jenis'] === 'ziyadah') {
                $scores[] = (int) $s['nilai'];
            }
            if ($s['catatan'] && trim($s['catatan']) !== '') {
                $lastCatatan = $s['catatan'];
            }
        }

        $avgScore = count($scores) > 0 ? round(array_sum($scores) / count($scores), 1) : 0;
        $totalHafal = $this->hafalanModel->countHafal($studentId, $programId);
        
        $adabScore = $totalSetoran > 15 ? 90 : ($totalSetoran > 8 ? 80 : 70);

        $report = $this->reportModel
            ->where('program_id', $programId)
            ->where('student_id', $studentId)
            ->first();

        $fashahahVal = $report ? $report['fashahah'] : round($avgScore ?: 80);
        $tajwidVal   = $report ? $report['tajwid'] : round($avgScore ?: 80);
        $adabVal     = $report ? $report['adab'] : $adabScore;
        $catatanVal  = $report ? $report['catatan'] : ($lastCatatan ?: 'Ananda telah mengikuti program tahfidz dengan baik. Harap pertahankan kedisiplinan murojaah secara mandiri di rumah agar hafalan tetap terjaga kokoh (mutqin).');

        return view('guru/tahfidz/report_setup', [
            'title'            => 'Persiapan Rapor Tahfidz',
            'teacher'          => $teacher,
            'program'          => $program,
            'selectedProgram'  => $program,
            'student'          => $student,
            'period'           => $period,
            'totalSetoran'     => $totalSetoran,
            'avgScore'         => $avgScore,
            'totalHafal'       => $totalHafal,
            'fashahahVal'      => $fashahahVal,
            'tajwidVal'        => $tajwidVal,
            'adabVal'          => $adabVal,
            'catatanVal'       => $catatanVal,
        ]);
    }

    public function saveReport()
    {
        if ($redirect = $this->checkAccess()) return $redirect;

        $teacher = $this->getTeacher();
        if (!$teacher) {
            return redirect()->to('/guru/dashboard')->with('error', 'Data guru tidak ditemukan.');
        }

        $programId = (int) $this->request->getPost('program_id');
        $studentId = (int) $this->request->getPost('student_id');
        $fashahah  = (int) $this->request->getPost('fashahah');
        $tajwid    = (int) $this->request->getPost('tajwid');
        $adab      = (int) $this->request->getPost('adab');
        $catatan   = trim($this->request->getPost('catatan') ?? '');

        if (!$programId || !$studentId) {
            return redirect()->back()->with('error', 'Data tidak lengkap.');
        }

        $existing = $this->reportModel
            ->where('program_id', $programId)
            ->where('student_id', $studentId)
            ->first();

        $data = [
            'program_id' => $programId,
            'student_id' => $studentId,
            'fashahah'   => $fashahah,
            'tajwid'     => $tajwid,
            'adab'       => $adab,
            'catatan'    => $catatan,
            'created_by' => $teacher['id']
        ];

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

        return redirect()->to("/guru/tahfidz/student-report?program_id={$programId}&student_id={$studentId}");
    }
}

