<?php

namespace App\Models;

use CodeIgniter\Model;

class TahfidzHafalanModel extends Model
{
    protected $table            = 'tahfidz_hafalan';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'array';
    protected $useSoftDeletes   = false;
    protected $allowedFields    = [
        'program_id', 'student_id', 'surah_id',
        'is_hafal', 'hafal_date', 'verified_by', 'catatan'
    ];

    protected $useTimestamps = true;
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';

    /**
     * Ambil semua status hafalan seorang siswa di satu program.
     * Return: [surah_id => row, ...]
     */
    public function getByStudentProgram(int $studentId, int $programId): array
    {
        $rows = $this
            ->where('student_id', $studentId)
            ->where('program_id', $programId)
            ->findAll();

        $map = [];
        foreach ($rows as $r) {
            $map[$r['surah_id']] = $r;
        }
        return $map;
    }

    /**
     * Simpan massal status hafalan (dari form ceklis 114 surah).
     * $hafalSurahIds = array of surah_id yang ditandai hafal.
     */
    public function saveBulk(int $studentId, int $programId, int $teacherId, array $hafalSurahIds): void
    {
        $db  = db_connect();
        $now = date('Y-m-d H:i:s');

        // Ambil status lama
        $existing = $this
            ->where('student_id', $studentId)
            ->where('program_id', $programId)
            ->findAll();

        $existingMap = [];
        foreach ($existing as $e) {
            $existingMap[$e['surah_id']] = $e;
        }

        $hafalSet = array_flip($hafalSurahIds); // fast lookup

        // Loop surah 1-114
        for ($surahId = 1; $surahId <= 114; $surahId++) {
            $shouldBeHafal = isset($hafalSet[$surahId]);
            $currentRow    = $existingMap[$surahId] ?? null;
            $isCurrentHafal = $currentRow ? (bool) $currentRow['is_hafal'] : false;

            if ($shouldBeHafal && !$isCurrentHafal) {
                // Tandai hafal baru
                if ($currentRow) {
                    $db->table('tahfidz_hafalan')
                       ->where('id', $currentRow['id'])
                       ->update([
                           'is_hafal'    => 1,
                           'hafal_date'  => date('Y-m-d'),
                           'verified_by' => $teacherId,
                           'updated_at'  => $now,
                       ]);
                } else {
                    $db->table('tahfidz_hafalan')->insert([
                        'program_id'  => $programId,
                        'student_id'  => $studentId,
                        'surah_id'    => $surahId,
                        'is_hafal'    => 1,
                        'hafal_date'  => date('Y-m-d'),
                        'verified_by' => $teacherId,
                        'created_at'  => $now,
                        'updated_at'  => $now,
                    ]);
                }
            } elseif (!$shouldBeHafal && $isCurrentHafal) {
                // Batal hafal
                $db->table('tahfidz_hafalan')
                   ->where('id', $currentRow['id'])
                   ->update([
                       'is_hafal'   => 0,
                       'hafal_date' => null,
                       'updated_at' => $now,
                   ]);
            }
        }
    }

    /**
     * Hitung total surah yang sudah hafal untuk satu siswa per program.
     */
    public function countHafal(int $studentId, int $programId): int
    {
        return $this
            ->where('student_id', $studentId)
            ->where('program_id', $programId)
            ->where('is_hafal', 1)
            ->countAllResults();
    }

    /**
     * Rekap hafalan per siswa dalam satu program (untuk laporan admin/guru).
     */
    public function getRekapByProgram(int $programId, ?int $classroomId = null): array
    {
        $db = db_connect();
        $sql = "
            SELECT
                s.id, s.nis, s.full_name, s.gender,
                COUNT(CASE WHEN th.is_hafal = 1 THEN 1 END) as total_hafal,
                MAX(th.hafal_date) as last_hafal_date
            FROM tahfidz_program_students tps
            JOIN students s ON s.id = tps.student_id
            LEFT JOIN student_academic_histories sah ON sah.student_id = s.id AND sah.academic_period_id = (SELECT id FROM academic_periods WHERE is_active = 1 LIMIT 1)
            LEFT JOIN tahfidz_hafalan th
                   ON th.student_id = tps.student_id
                   AND th.program_id = tps.program_id
            WHERE tps.program_id = ?
              AND s.deleted_at IS NULL
        ";
        $params = [$programId];

        if ($classroomId) {
            $sql .= " AND sah.classroom_id = ?";
            $params[] = $classroomId;
        }

        $sql .= " GROUP BY s.id ORDER BY total_hafal DESC, s.full_name ASC";
        return $db->query($sql, $params)->getResultArray();
    }

    /**
     * Statistik hafalan per juz untuk satu siswa (untuk halaman progress juz).
     * Return: [juz_number => [total_surah_in_juz, hafal_count]]
     */
    public function getProgressPerJuz(int $studentId, int $programId): array
    {
        $db = db_connect();

        // Total surah per juz
        $juzTotals = $db->query("
            SELECT juz_start, COUNT(*) as total
            FROM quran_surahs
            GROUP BY juz_start
        ")->getResultArray();

        $totalsMap = [];
        foreach ($juzTotals as $j) {
            $totalsMap[$j['juz_start']] = (int) $j['total'];
        }

        // Hafalan per juz
        $hafalData = $db->query("
            SELECT qs.juz_start, COUNT(th.id) as hafal
            FROM tahfidz_hafalan th
            JOIN quran_surahs qs ON qs.id = th.surah_id
            WHERE th.student_id = ?
              AND th.program_id = ?
              AND th.is_hafal = 1
            GROUP BY qs.juz_start
        ", [$studentId, $programId])->getResultArray();

        $hafalMap = [];
        foreach ($hafalData as $h) {
            $hafalMap[$h['juz_start']] = (int) $h['hafal'];
        }

        $result = [];
        for ($juz = 1; $juz <= 30; $juz++) {
            $total = $totalsMap[$juz] ?? 0;
            $hafal = $hafalMap[$juz] ?? 0;
            $result[$juz] = [
                'juz'         => $juz,
                'total_surah' => $total,
                'hafal'       => $hafal,
                'persen'      => $total > 0 ? round(($hafal / $total) * 100) : 0,
            ];
        }
        return $result;
    }
}
