<?php

namespace App\Controllers\Admin;

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\ClassroomModel;
use App\Models\StudentModel;
use App\Models\AcademicPeriodModel;

class TahfidzAdmin extends BaseController
{
    protected $programModel;
    protected $setoranModel;
    protected $hafalanModel;
    protected $surahModel;
    protected $teacherModel;
    protected $classroomModel;
    protected $studentModel;
    protected $periodModel;

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

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

    // ── DAFTAR PROGRAM ──────────────────────────────────────────────
    public function index()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activePeriod = $this->periodModel->getActive();
        $selectedPeriodId = $this->request->getGet('period_id') ?: ($activePeriod['id'] ?? null);

        $programs = $this->programModel->getAllWithPeriod($selectedPeriodId);

        // Tambahkan info jumlah guru dan siswa per program
        foreach ($programs as &$p) {
            $p['teacher_count'] = count($this->programModel->getTeachers($p['id']));
            $p['student_count'] = count($this->programModel->getStudents($p['id']));
        }
        unset($p);

        return view('admin/tahfidz/index', [
            'title'           => 'Program Tahfidz',
            'activePeriod'    => $activePeriod,
            'selectedPeriodId'=> $selectedPeriodId,
            'periods'         => $this->periodModel->getAllWithYear(),
            'programs'        => $programs,
        ]);
    }

    // ── BUAT PROGRAM BARU ───────────────────────────────────────────
    public function create()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

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

        return view('admin/tahfidz/create', [
            'title'        => 'Buat Program Tahfidz',
            'activePeriod' => $activePeriod,
            'periods'      => $this->periodModel->getAllWithYear(),
            'teachers'     => $this->teacherModel->where('is_active', 1)->orderBy('name', 'ASC')->findAll(),
        ]);
    }

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

        $rules = [
            'name'               => 'required|min_length[3]|max_length[100]',
            'type'               => 'required|in_list[kbm,pk,boarding]',
            'academic_period_id' => 'required|numeric',
        ];

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

        $programId = $this->programModel->insert([
            'name'               => $this->request->getPost('name'),
            'type'               => $this->request->getPost('type'),
            'academic_period_id' => $this->request->getPost('academic_period_id'),
            'description'        => $this->request->getPost('description'),
            'is_active'          => 1,
            'created_by'         => session()->get('user_id'),
        ]);

        if (!$programId) {
            return redirect()->back()->withInput()->with('error', 'Gagal membuat program tahfidz.');
        }

        // Simpan guru pengampu
        $teacherIds = $this->request->getPost('teacher_ids') ?? [];
        if (!empty($teacherIds)) {
            $this->programModel->saveTeachers($programId, $teacherIds);
        }

        // Simpan WA Group ID
        $waGroupId = trim($this->request->getPost('wa_group_id') ?? '');
        $db = \Config\Database::connect();
        $db->table('settings')->insert([
            'setting_key'   => 'wa_group_id_' . $programId,
            'setting_value' => $waGroupId,
        ]);

        return redirect()->to('/admin/tahfidz/programs/' . $programId . '/students')
            ->with('success', 'Program tahfidz berhasil dibuat. Sekarang tambahkan siswa.');
    }

    // ── EDIT PROGRAM ────────────────────────────────────────────────
    public function edit($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $program = $this->programModel->find($id);
        if (!$program) {
            return redirect()->to('/admin/tahfidz')->with('error', 'Program tidak ditemukan.');
        }

        $assignedTeachers = $this->programModel->getTeachers($id);
        $assignedIds      = array_column($assignedTeachers, 'id');

        return view('admin/tahfidz/edit', [
            'title'        => 'Edit Program Tahfidz',
            'program'      => $program,
            'periods'      => $this->periodModel->getAllWithYear(),
            'teachers'     => $this->teacherModel->where('is_active', 1)->orderBy('name', 'ASC')->findAll(),
            'assignedIds'  => $assignedIds,
        ]);
    }

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

        $program = $this->programModel->find($id);
        if (!$program) {
            return redirect()->to('/admin/tahfidz')->with('error', 'Program tidak ditemukan.');
        }

        $this->programModel->update($id, [
            'name'        => $this->request->getPost('name'),
            'type'        => $this->request->getPost('type'),
            'description' => $this->request->getPost('description'),
            'is_active'   => $this->request->getPost('is_active') ? 1 : 0,
        ]);

        $teacherIds = $this->request->getPost('teacher_ids') ?? [];
        $this->programModel->saveTeachers($id, $teacherIds);

        // Update WA Group ID
        $waGroupId = trim($this->request->getPost('wa_group_id') ?? '');
        $db = \Config\Database::connect();
        $exists = $db->table('settings')->where('setting_key', 'wa_group_id_' . $id)->countAllResults();
        if ($exists) {
            $db->table('settings')->where('setting_key', 'wa_group_id_' . $id)->update(['setting_value' => $waGroupId]);
        } else {
            $db->table('settings')->insert(['setting_key' => 'wa_group_id_' . $id, 'setting_value' => $waGroupId]);
        }

        return redirect()->to('/admin/tahfidz')
            ->with('success', 'Program tahfidz berhasil diperbarui.');
    }

    // ── HAPUS PROGRAM ───────────────────────────────────────────────
    public function delete($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $this->programModel->delete($id);
        return redirect()->to('/admin/tahfidz')->with('success', 'Program berhasil dihapus.');
    }

    // ── AJAX: Dapatkan Daftar Grup WA dari Sidobe ────────────────────
    public function getWaGroups()
    {
        if ($redirect = $this->checkLogin()) {
            return $this->response->setJSON(['success' => false, 'message' => 'Sesi berakhir.']);
        }

        $db = \Config\Database::connect();
        $apiKey = $db->table('settings')->where('setting_key', 'wa_sidobe_api_key')->get()->getRowArray()['setting_value'] ?? '';
        $sender = $db->table('settings')->where('setting_key', 'wa_sidobe_sender')->get()->getRowArray()['setting_value'] ?? '';

        if (empty($apiKey)) {
            return $this->response->setJSON(['success' => false, 'message' => 'API Key Sidobe belum diatur di Pengaturan WA.']);
        }

        $url = 'https://api.sidobe.com/wa/v1/whatsapp-groups';
        if (!empty($sender)) {
            $cleanSender = preg_replace('/\D/', '', $sender);
            if (str_starts_with($cleanSender, '0')) {
                $cleanSender = '62' . substr($cleanSender, 1);
            }
            $url .= '?sender_phone=' . urlencode($cleanSender) . '&from_phone=' . urlencode($cleanSender) . '&sender=' . urlencode($cleanSender);
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => [
                'X-Secret-Key: ' . $apiKey
            ],
            CURLOPT_IPRESOLVE      => CURL_IPRESOLVE_V4,
            CURLOPT_CONNECTTIMEOUT => 15,
            CURLOPT_TIMEOUT        => 30,
            CURLOPT_SSL_VERIFYPEER => false,
        ]);
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if ($response === false) {
            $err = curl_error($ch);
            curl_close($ch);
            return $this->response->setJSON(['success' => false, 'message' => 'cURL error: ' . $err]);
        }
        curl_close($ch);

        if ($httpCode !== 200) {
            $msg = 'Gagal mengambil grup dari Sidobe (HTTP ' . $httpCode . ')';
            $respObj = json_decode($response, true);
            if ($respObj && !empty($respObj['message'])) {
                $msg .= ': ' . $respObj['message'];
            } elseif ($respObj && !empty($respObj['error'])) {
                $msg .= ': ' . $respObj['error'];
            } else {
                $msg .= ': ' . substr($response, 0, 150);
            }
            return $this->response->setJSON(['success' => false, 'message' => $msg]);
        }

        $result = json_decode($response, true);
        if (isset($result['is_success']) && $result['is_success'] === true) {
            return $this->response->setJSON(['success' => true, 'data' => $result['data']]);
        }

        return $this->response->setJSON(['success' => false, 'message' => $result['message'] ?? 'Terjadi kesalahan.']);
    }

    // ── KELOLA SISWA PROGRAM ────────────────────────────────────────
    public function students($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $program = $this->programModel->find($id);
        if (!$program) {
            return redirect()->to('/admin/tahfidz')->with('error', 'Program tidak ditemukan.');
        }

        $enrolledStudents = $this->programModel->getStudents($id);
        $enrolledIds      = array_column($enrolledStudents, 'id');

        $activePeriod = $this->periodModel->getActive();
        $classrooms   = $this->classroomModel->getAllWithRelations();

        $db = db_connect();

        // Hitung siswa aktif per kelas pada periode aktif
        $studentCountMap = [];
        if ($activePeriod) {
            $counts = $db->query("
                SELECT sah.classroom_id, COUNT(*) as total
                FROM student_academic_histories sah
                JOIN students s ON s.id = sah.student_id
                WHERE sah.academic_period_id = ?
                  AND sah.status = 'Aktif'
                  AND s.deleted_at IS NULL
                GROUP BY sah.classroom_id
            ", [$activePeriod['id']])->getResultArray();
            foreach ($counts as $c) {
                $studentCountMap[$c['classroom_id']] = (int) $c['total'];
            }
        }

        // Cari kelas mana saja yang sudah ada setidaknya 1 siswa enrolled di program ini
        $enrolledClassroomIds = [];
        if (!empty($enrolledIds) && $activePeriod) {
            $rows = $db->query("
                SELECT DISTINCT sah.classroom_id
                FROM student_academic_histories sah
                WHERE sah.student_id IN (" . implode(',', array_map('intval', $enrolledIds)) . ")
                  AND sah.academic_period_id = ?
            ", [$activePeriod['id']])->getResultArray();
            $enrolledClassroomIds = array_column($rows, 'classroom_id');
        }

        // Ambil semua siswa aktif untuk dipilih satu-satu secara fleksibel di semua program
        $allStudents = [];
        if ($activePeriod) {
            $allStudents = $db->query("
                SELECT DISTINCT s.id, s.nis, s.full_name, s.gender,
                       c.name as classroom_name, c.id as classroom_id
                FROM students s
                JOIN student_academic_histories sah ON sah.student_id = s.id
                JOIN classrooms c ON c.id = sah.classroom_id
                WHERE s.deleted_at IS NULL
                  AND sah.status = 'Aktif'
                  AND sah.academic_period_id = ?
                ORDER BY c.name ASC, s.full_name ASC
            ", [$activePeriod['id']])->getResultArray();
        }

        return view('admin/tahfidz/students', [
            'title'                => 'Kelola Siswa: ' . $program['name'],
            'program'              => $program,
            'enrolledStudents'     => $enrolledStudents,
            'enrolledIds'          => $enrolledIds,
            'enrolledClassroomIds' => $enrolledClassroomIds,
            'classrooms'           => $classrooms,
            'studentCountMap'      => $studentCountMap,
            'allStudents'          => $allStudents,
            'activePeriod'         => $activePeriod,
        ]);
    }

    /**
     * AJAX: Tambah siswa dari BEBERAPA kelas sekaligus (untuk PK/KBM).
     * Menerima array classroom_ids[] dan period_id.
     */
    public function addFromClassrooms($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $classroomIds = $this->request->getPost('classroom_ids') ?? [];
        $periodId     = (int) $this->request->getPost('period_id');

        if (empty($classroomIds) || !$periodId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Pilih minimal 1 kelas.']);
        }

        $totalAdded = 0;
        foreach ($classroomIds as $classroomId) {
            $totalAdded += $this->programModel->addStudentsFromClassroom($id, (int) $classroomId, $periodId);
        }

        $totalNow = count($this->programModel->getStudents($id));

        return $this->response->setJSON([
            'success'    => true,
            'message'    => "{$totalAdded} siswa baru berhasil ditambahkan dari " . count($classroomIds) . " kelas.",
            'added'      => $totalAdded,
            'total_now'  => $totalNow,
        ]);
    }

    /**
     * AJAX: Tambah beberapa siswa terpilih secara massal (untuk Tab 2).
     */
    public function addStudentsBulk($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $studentIds = $this->request->getPost('student_ids') ?? [];
        if (empty($studentIds)) {
            return $this->response->setJSON(['success' => false, 'message' => 'Pilih minimal 1 siswa.']);
        }

        $db  = db_connect();
        $now = date('Y-m-d H:i:s');

        // Tarik data siswa yang sudah terdaftar
        $existing = $db->table('tahfidz_program_students')
            ->select('student_id')
            ->where('program_id', $id)
            ->get()->getResultArray();
        $existingIds = array_column($existing, 'student_id');

        $toInsert = [];
        foreach ($studentIds as $sId) {
            $sId = (int)$sId;
            if (!in_array($sId, $existingIds)) {
                $toInsert[] = [
                    'program_id' => $id,
                    'student_id' => $sId,
                    'joined_at'  => date('Y-m-d'),
                    'created_at' => $now,
                ];
            }
        }

        if (!empty($toInsert)) {
            $db->table('tahfidz_program_students')->insertBatch($toInsert);
        }

        $totalNow = count($this->programModel->getStudents($id));

        return $this->response->setJSON([
            'success'   => true,
            'message'   => count($toInsert) . ' siswa baru berhasil ditambahkan.',
            'added'     => count($toInsert),
            'total_now' => $totalNow,
        ]);
    }

    /**
     * AJAX: Toggle satu siswa (tambah/hapus) dari program boarding.
     */
    public function toggleStudent($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $studentId = (int) $this->request->getPost('student_id');
        if (!$studentId) {
            return $this->response->setJSON(['success' => false]);
        }

        $action = $this->programModel->toggleStudent($id, $studentId);

        return $this->response->setJSON([
            'success' => true,
            'action'  => $action, // 'added' atau 'removed'
        ]);
    }

    /**
     * Hapus semua siswa dari program (reset).
     */
    public function clearStudents($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $this->programModel->clearStudents($id);
        return redirect()->to('/admin/tahfidz/programs/' . $id . '/students')
            ->with('success', 'Semua siswa berhasil dihapus dari program.');
    }

    // ── DASHBOARD MONITORING (ADMIN) ─────────────────────────────────
    public function dashboard()
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $activePeriod = $this->periodModel->getActive();
        if (!$activePeriod) {
            return redirect()->to('/admin/tahfidz')->with('error', 'Belum ada periode aktif.');
        }

        $programs = $this->programModel->getAllWithPeriod($activePeriod['id']);

        $dashData = [];
        foreach ($programs as $p) {
            $students = $this->programModel->getStudents($p['id']);
            $teachers = $this->programModel->getTeachers($p['id']);

            $startOfWeek = date('Y-m-d', strtotime('monday this week'));
            $endOfWeek   = date('Y-m-d', strtotime('sunday this week'));
            $rekapMinggu = $this->setoranModel->getRekapByProgram($p['id'], $startOfWeek, $endOfWeek);

            $hafalRekap  = $this->hafalanModel->getRekapByProgram($p['id']);
            $totalHafal  = array_sum(array_column($hafalRekap, 'total_hafal'));
            $maxHafal    = !empty($hafalRekap) ? max(array_column($hafalRekap, 'total_hafal')) : 0;

            $dashData[] = [
                'program'         => $p,
                'total_students'  => count($students),
                'total_teachers'  => count($teachers),
                'setoran_minggu'  => count($rekapMinggu),
                'total_hafal_all' => $totalHafal,
                'max_hafal'       => $maxHafal,
                'top_hafalan'     => array_slice($hafalRekap, 0, 5),
            ];
        }

        // 1. Keaktifan Kelas (Rata-rata frekuensi setoran per kelas)
        $kelasKeaktifan = $this->programModel->db->table('tahfidz_setoran ts')
            ->select('c.name as classroom_name, COUNT(ts.id) as total_setoran')
            ->join('student_academic_histories sah', 'sah.student_id = ts.student_id')
            ->join('classrooms c', 'c.id = sah.classroom_id')
            ->where('sah.academic_period_id', $activePeriod['id'])
            ->groupBy('c.id')
            ->orderBy('total_setoran', 'DESC')
            ->get()
            ->getResultArray();

        // 2. Daftar Murid Kritis (Belum menyetor hafalan >= 14 hari)
        $twoWeeksAgo = date('Y-m-d', strtotime('-14 days'));
        $criticalStudents = $this->studentModel->db->table('student_academic_histories sah')
            ->select('s.id as student_id, s.full_name, c.name as classroom_name, MAX(ts.setoran_date) as last_setoran_date, qs.name_latin as surah_name, ts.catatan')
            ->join('students s', 's.id = sah.student_id')
            ->join('classrooms c', 'c.id = sah.classroom_id')
            ->join('tahfidz_setoran ts', 'ts.student_id = s.id', 'left')
            ->join('quran_surahs qs', 'qs.id = ts.surah_id', 'left')
            ->where('sah.academic_period_id', $activePeriod['id'])
            ->where('sah.status', 'Aktif')
            ->groupBy('s.id')
            ->having('last_setoran_date <', $twoWeeksAgo)
            ->orHaving('last_setoran_date IS NULL')
            ->orderBy('last_setoran_date', 'ASC')
            ->limit(10)
            ->get()
            ->getResultArray();

        return view('admin/tahfidz/dashboard', [
            'title'            => 'Dashboard Tahfidz',
            'activePeriod'     => $activePeriod,
            'dashData'         => $dashData,
            'kelasKeaktifan'   => $kelasKeaktifan,
            'criticalStudents' => $criticalStudents,
        ]);
    }

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

        $activePeriod = $this->periodModel->getActive();
        if (!$activePeriod) {
            return redirect()->to('/admin/tahfidz')->with('error', 'Belum ada periode aktif.');
        }

        $programs = $this->programModel->getAllWithPeriod($activePeriod['id']);
        $dashData = [];
        foreach ($programs as $p) {
            $students = $this->programModel->getStudents($p['id']);
            $teachers = $this->programModel->getTeachers($p['id']);
            $startOfWeek = date('Y-m-d', strtotime('monday this week'));
            $endOfWeek   = date('Y-m-d', strtotime('sunday this week'));
            $rekapMinggu = $this->setoranModel->getRekapByProgram($p['id'], $startOfWeek, $endOfWeek);
            $hafalRekap  = $this->hafalanModel->getRekapByProgram($p['id']);
            $totalHafal  = array_sum(array_column($hafalRekap, 'total_hafal'));
            $maxHafal    = !empty($hafalRekap) ? max(array_column($hafalRekap, 'total_hafal')) : 0;

            $dashData[] = [
                'program'         => $p,
                'total_students'  => count($students),
                'total_teachers'  => count($teachers),
                'setoran_minggu'  => count($rekapMinggu),
                'total_hafal_all' => $totalHafal,
                'max_hafal'       => $maxHafal,
                'top_hafalan'     => array_slice($hafalRekap, 0, 5),
            ];
        }

        // Keaktifan Kelas
        $kelasKeaktifan = $this->programModel->db->table('tahfidz_setoran ts')
            ->select('c.name as classroom_name, COUNT(ts.id) as total_setoran')
            ->join('student_academic_histories sah', 'sah.student_id = ts.student_id')
            ->join('classrooms c', 'c.id = sah.classroom_id')
            ->where('sah.academic_period_id', $activePeriod['id'])
            ->groupBy('c.id')
            ->orderBy('total_setoran', 'DESC')
            ->get()
            ->getResultArray();

        // Murid Kritis
        $twoWeeksAgo = date('Y-m-d', strtotime('-14 days'));
        $criticalStudents = $this->studentModel->db->table('student_academic_histories sah')
            ->select('s.id as student_id, s.full_name, c.name as classroom_name, MAX(ts.setoran_date) as last_setoran_date, qs.name_latin as surah_name, ts.catatan')
            ->join('students s', 's.id = sah.student_id')
            ->join('classrooms c', 'c.id = sah.classroom_id')
            ->join('tahfidz_setoran ts', 'ts.student_id = s.id', 'left')
            ->join('quran_surahs qs', 'qs.id = ts.surah_id', 'left')
            ->where('sah.academic_period_id', $activePeriod['id'])
            ->where('sah.status', 'Aktif')
            ->groupBy('s.id')
            ->having('last_setoran_date <', $twoWeeksAgo)
            ->orHaving('last_setoran_date IS NULL')
            ->orderBy('last_setoran_date', 'ASC')
            ->limit(15)
            ->get()
            ->getResultArray();

        return view('admin/tahfidz/export_recap', [
            'activePeriod'     => $activePeriod,
            'dashData'         => $dashData,
            'kelasKeaktifan'   => $kelasKeaktifan,
            'criticalStudents' => $criticalStudents,
        ]);
    }
}
