<?php

namespace App\Controllers\Guru;

use App\Controllers\BaseController;
use App\Models\TeachingJournalModel;
use App\Models\JournalAttendanceModel;
use App\Models\TeacherModel;
use App\Models\TeachingAssignmentModel;
use App\Models\AcademicPeriodModel;

class JournalController extends BaseController
{
    protected $journalModel;
    protected $attendanceModel;
    protected $teacherModel;
    protected $assignmentModel;
    protected $periodModel;

    public function __construct()
    {
        $this->journalModel     = new TeachingJournalModel();
        $this->attendanceModel  = new JournalAttendanceModel();
        $this->teacherModel     = new TeacherModel();
        $this->assignmentModel  = new TeachingAssignmentModel();
        $this->periodModel      = new AcademicPeriodModel();
    }

    private function checkLogin()
    {
        if (!session()->get('logged_in')) {
            return redirect()->to('/login');
        }
        return null;
    }

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

    // ── DAFTAR JURNAL ──────────────────────────────────────────

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

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

        $activePeriod = $this->periodModel->where('is_active', 1)->first();
        $periodId     = $activePeriod['id'] ?? null;
        $classId      = $this->request->getGet('kelas') ? (int)$this->request->getGet('kelas') : null;
        $subjectId    = $this->request->getGet('mapel') ? (int)$this->request->getGet('mapel') : null;
        $search       = $this->request->getGet('q');

        $journals   = $this->journalModel->getByTeacher($teacher['id'], $periodId, $classId, $subjectId, $search);
        $classrooms = $this->assignmentModel->getTeacherClassrooms($teacher['id']);
        $subjects   = $this->assignmentModel->getTeacherSubjects($teacher['id']);

        $data = [
            'title'     => 'Jurnal Mengajar',
            'journals'  => $journals,
            'classrooms'=> $classrooms,
            'subjects'  => $subjects,
            'activePeriod' => $activePeriod,
        ];

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

    // ── FORM TAMBAH / EDIT ─────────────────────────────────────

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

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

        $activePeriod = $this->periodModel->where('is_active', 1)->first();
        if (!$activePeriod) {
            return redirect()->to('/guru/journal')->with('error', 'Tidak ada semester aktif.');
        }

        $classrooms = $this->assignmentModel->getTeacherClassrooms($teacher['id'], $activePeriod['id']);
        $subjects   = $this->assignmentModel->getTeacherSubjects($teacher['id'], $activePeriod['id']);

        $data = [
            'title'        => 'Tambah Jurnal',
            'classrooms'   => $classrooms,
            'subjects'     => $subjects,
            'activePeriod' => $activePeriod,
            'teacher'      => $teacher,
        ];

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

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

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

        $activePeriod = $this->periodModel->where('is_active', 1)->first();
        if (!$activePeriod) {
            return $this->response->setJSON(['success' => false, 'message' => 'Tidak ada semester aktif.']);
        }

        $classroomId = (int)$this->request->getPost('classroom_id');
        $subjectId   = (int)$this->request->getPost('school_subject_id');
        $meetingDate = $this->request->getPost('meeting_date');
        $startPeriod = (int)$this->request->getPost('start_period');
        $endPeriod   = (int)$this->request->getPost('end_period');
        $topic       = $this->request->getPost('topic');
        $notes       = $this->request->getPost('notes');
        $absenteesRaw = $this->request->getPost('absentees');
        $absentees    = $absenteesRaw ? json_decode($absenteesRaw, true) : [];

        // Validasi
        if (empty($classroomId) || empty($subjectId) || empty($meetingDate) || empty($startPeriod) || empty($endPeriod)) {
            return $this->response->setJSON(['success' => false, 'message' => 'Data tidak lengkap.']);
        }

        // Hitung jumlah siswa di kelas
        $db = db_connect();
        $totalStudents = (int) $db->table('student_academic_histories')
            ->where('classroom_id', $classroomId)
            ->where('academic_period_id', $activePeriod['id'])
            ->where('status', 'Aktif')
            ->countAllResults();

        // Hitung absent
        $sickCount   = 0;
        $permitCount = 0;
        $absentCount = 0;
        $absentData  = [];

        if (!empty($absentees)) {
            foreach ($absentees as $a) {
                $s = $a['status'] ?? 'Alpha';
                if ($s === 'Sakit')    $sickCount++;
                elseif ($s === 'Izin')  $permitCount++;
                else                    $absentCount++;
                $absentData[] = [
                    'student_id' => (int)$a['student_id'],
                    'status'     => $s,
                ];
            }
        }

        $presentCount = $totalStudents - $sickCount - $permitCount - $absentCount;

        // Meeting number
        $meetingNumber = $this->journalModel->getNextMeetingNumber(
            $teacher['id'], $activePeriod['id'], $classroomId, $subjectId
        );

        // Simpan jurnal
        $journalData = [
            'teacher_id'          => $teacher['id'],
            'academic_period_id'  => $activePeriod['id'],
            'classroom_id'        => $classroomId,
            'school_subject_id'   => $subjectId,
            'meeting_date'        => $meetingDate,
            'start_period'        => $startPeriod,
            'end_period'          => $endPeriod,
            'meeting_number'      => $meetingNumber,
            'topic'               => $topic,
            'notes'               => $notes,
            'total_students'      => $totalStudents,
            'total_present'       => max(0, $presentCount),
            'total_sick'          => $sickCount,
            'total_permit'        => $permitCount,
            'total_absent'        => $absentCount,
        ];

        $journalId = $this->journalModel->insert($journalData);
        if (!$journalId) {
            return $this->response->setJSON(['success' => false, 'message' => 'Gagal menyimpan jurnal.']);
        }

        // Simpan presensi (yang tidak hadir)
        if (!empty($absentData)) {
            foreach ($absentData as $ad) {
                $ad['journal_id'] = $journalId;
                $this->attendanceModel->insert($ad);
            }
        }

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

    // ── DETAIL JURNAL (untuk cetak & view) ─────────────────────

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

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

        $journal = $this->journalModel->getDetail($id, $teacher['id']);
        if (!$journal) {
            return redirect()->to('/guru/journal')->with('error', 'Jurnal tidak ditemukan.');
        }

        $absentees = $this->attendanceModel->getAbsenteesByJournal($id);

        $data = [
            'title'    => 'Detail Jurnal',
            'j'        => $journal,
            'absentees'=> $absentees,
        ];

        return view('guru/journal/detail', $data);
    }

    // ── DELETE ─────────────────────────────────────────────────

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

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

        $journal = $this->journalModel->where('id', $id)->where('teacher_id', $teacher['id'])->first();
        if (!$journal) {
            return $this->response->setJSON(['success' => false, 'message' => 'Jurnal tidak ditemukan.']);
        }

        // Hapus attendance dulu
        $this->attendanceModel->deleteByJournal($id);
        // Soft delete jurnal
        $this->journalModel->delete($id);

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

    // ── GET TP BY KELAS+MAPEL (AJAX untuk form) ───────────────

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

        $classroomId   = (int)$this->request->getGet('classroom_id');
        $periodId      = (int)$this->request->getGet('academic_period_id');

        if (empty($classroomId) || empty($periodId)) {
            return $this->response->setJSON(['students' => []]);
        }

        $db = db_connect();
        $students = $db->query('SELECT sah.student_id, s.nisn, s.full_name
            FROM student_academic_histories sah
            INNER JOIN students s ON s.id = sah.student_id
            WHERE sah.classroom_id = ?
              AND sah.academic_period_id = ?
              AND sah.status = \'Aktif\'
              AND s.status = \'Aktif\'
              AND s.deleted_at IS NULL
            ORDER BY s.full_name ASC', [$classroomId, $periodId])->getResultArray();

        return $this->response->setJSON(['students' => $students]);
    }

    // ── CETAK JURNAL ───────────────────────────────────────────    // ── CETAK JURNAL ───────────────────────────────────────────

    public function print(int $classroomId, int $subjectId)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

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

        $activePeriod = $this->periodModel->select('academic_periods.*, academic_years.name AS academic_year_name')
            ->join('academic_years', 'academic_years.id = academic_periods.academic_year_id')
            ->where('academic_periods.is_active', 1)
            ->first();
        if (!$activePeriod) {
            return redirect()->to('/guru/journal')->with('error', 'Tidak ada semester aktif.');
        }

        $classroom = db_connect()->table('classrooms')->where('id', $classroomId)->where('deleted_at', null)->get()->getRowArray();
        $subject   = db_connect()->table('school_subjects')->where('id', $subjectId)->get()->getRowArray();

        if (!$classroom || !$subject) {
            return redirect()->to('/guru/journal')->with('error', 'Kelas atau mapel tidak ditemukan.');
        }

        $journals = $this->journalModel
            ->where('teacher_id', $teacher['id'])
            ->where('academic_period_id', $activePeriod['id'])
            ->where('classroom_id', $classroomId)
            ->where('school_subject_id', $subjectId)
            ->where('deleted_at', null)
            ->orderBy('meeting_date', 'ASC')
            ->findAll();

        if (empty($journals)) {
            return redirect()->to('/guru/journal')->with('error', 'Belum ada jurnal untuk kelas dan mapel ini.');
        }

        // Ambil data absensi per jurnal
        $journalIds = array_column($journals, 'id');
        $allAbsentees = [];
        if (!empty($journalIds)) {
            $db = db_connect();
            $placeholders = implode(',', array_fill(0, count($journalIds), '?'));
            $absSql = "SELECT ja.*, s.full_name FROM journal_attendances ja
                       JOIN students s ON s.id = ja.student_id
                       WHERE ja.journal_id IN ({$placeholders})
                       ORDER BY ja.journal_id ASC, s.full_name ASC";
            $allAbsentees = $db->query($absSql, $journalIds)->getResultArray();
        }

        // Kelompokkan absensi per journal_id
        $absMap = [];
        foreach ($allAbsentees as $a) {
            $absMap[$a['journal_id']][] = $a;
        }

        // Ambil data PROTA untuk target JP
        $protaModel = new \App\Models\LearningDeviceProtaModel();
        $deviceModel = new \App\Models\LearningDeviceModel();
        $device = $deviceModel->where('user_id', $teacher['user_id'])
            ->where('school_subject_id', $subjectId)
            ->where('grade_id', $classroom['grade_id'])
            ->first();
        $targetJp = 0;
        if ($device) {
            $protaRows = $protaModel->where('learning_device_id', $device['id'])->findAll();
            foreach ($protaRows as $p) {
                $targetJp += (int)$p['allocated_hours'];
            }
        }

        // Data sekolah
        $school = db_connect()->table('school_settings')->limit(1)->get()->getRowArray();

        $data = [
            'title'     => 'Cetak Jurnal',
            'journals'  => $journals,
            'absMap'    => $absMap,
            'teacher'   => $teacher,
            'classroom' => $classroom,
            'subject'   => $subject,
            'period'    => $activePeriod,
            'targetJp'  => $targetJp,
            'school'    => $school,
        ];

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

    // ── CETAK SEMUA JURNAL (1 SEMESTER, SEMUA KELAS + MAPEL) ──

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

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

        $activePeriod = $this->periodModel->select('academic_periods.*, academic_years.name AS academic_year_name')
            ->join('academic_years', 'academic_years.id = academic_periods.academic_year_id')
            ->where('academic_periods.is_active', 1)
            ->first();
        if (!$activePeriod) {
            return redirect()->to('/guru/journal')->with('error', 'Tidak ada semester aktif.');
        }

        $journals = $this->journalModel
            ->select('
                teaching_journals.*,
                classrooms.name AS classroom_name,
                school_subjects.name AS subject_name
            ')
            ->join('classrooms', 'classrooms.id = teaching_journals.classroom_id')
            ->join('school_subjects', 'school_subjects.id = teaching_journals.school_subject_id')
            ->where('teaching_journals.teacher_id', $teacher['id'])
            ->where('teaching_journals.academic_period_id', $activePeriod['id'])
            ->where('teaching_journals.deleted_at', null)
            ->orderBy('classrooms.name', 'ASC')
            ->orderBy('school_subjects.name', 'ASC')
            ->orderBy('teaching_journals.meeting_date', 'ASC')
            ->findAll();

        if (empty($journals)) {
            return redirect()->to('/guru/journal')->with('error', 'Belum ada jurnal di semester ini.');
        }

        $journalIds = array_column($journals, 'id');
        $allAbsentees = [];
        if (!empty($journalIds)) {
            $db = db_connect();
            $placeholders = implode(',', array_fill(0, count($journalIds), '?'));
            $allAbsentees = $db->query(
                'SELECT ja.*, s.full_name FROM journal_attendances ja
                 JOIN students s ON s.id = ja.student_id
                 WHERE ja.journal_id IN (' . $placeholders . ')
                 ORDER BY ja.journal_id ASC, s.full_name ASC',
                $journalIds
            )->getResultArray();
        }

        $absMap = [];
        foreach ($allAbsentees as $a) {
            $absMap[$a['journal_id']][] = $a;
        }

        $school = db_connect()->table('school_settings')->limit(1)->get()->getRowArray();

        $data = [
            'title'     => 'Cetak Semua Jurnal',
            'journals'  => $journals,
            'absMap'    => $absMap,
            'teacher'   => $teacher,
            'period'    => $activePeriod,
            'school'    => $school,
        ];

        return view('guru/journal/print_all', $data);
    }
}