<?php

namespace App\Controllers\Guru;

use App\Controllers\BaseController;
use App\Models\StudentModel;
use App\Models\ViolationRuleModel;
use App\Models\StudentViolationModel;
use App\Models\ViolationSanctionModel;
use App\Models\AcademicPeriodModel;
use App\Models\ClassroomModel;

class ViolationController extends BaseController
{
    protected $studentModel;
    protected $ruleModel;
    protected $violationModel;
    protected $sanctionModel;
    protected $periodModel;
    protected $classroomModel;

    public function __construct()
    {
        $this->studentModel   = new StudentModel();
        $this->ruleModel      = new ViolationRuleModel();
        $this->violationModel = new StudentViolationModel();
        $this->sanctionModel  = new ViolationSanctionModel();
        $this->periodModel    = new AcademicPeriodModel();
        $this->classroomModel = new ClassroomModel();
    }

    private function getTeacherAndClasses($activePeriodId)
    {
        $role = session()->get('user_role');
        $userId = session()->get('user_id');
        $db = \Config\Database::connect();

        // Jika Admin/Superadmin, mereka mendapat seluruh kelas
        if (in_array($role, ['superadmin', 'admin'])) {
            $classrooms = $db->table('classrooms')
                ->select('id, name')
                ->where('deleted_at', null)
                ->orderBy('name', 'ASC')
                ->get()->getResultArray();
            return ['is_admin' => true, 'teacher' => null, 'classrooms' => $classrooms];
        }

        // Jika Guru BK
        $teacher = $db->table('teachers')
            ->select('id, name')
            ->where('user_id', $userId)
            ->get()->getRowArray();

        if (!$teacher) {
            return ['is_admin' => false, 'teacher' => null, 'classrooms' => []];
        }

        // Ambil kelas binaan dari bk_assignments
        $classrooms = $db->table('bk_assignments b')
            ->select('c.id, c.name')
            ->join('classrooms c', 'c.id = b.classroom_id')
            ->where('b.teacher_id', $teacher['id'])
            ->where('b.academic_period_id', $activePeriodId)
            ->orderBy('c.name', 'ASC')
            ->get()->getResultArray();

        return ['is_admin' => false, 'teacher' => $teacher, 'classrooms' => $classrooms];
    }

    public function index()
    {
        $activePeriod = $this->periodModel->getActive();
        if (!$activePeriod) {
            return redirect()->to('/dashboard')->with('error', 'Tidak ada semester/periode akademik yang sedang aktif.');
        }

        $access = $this->getTeacherAndClasses($activePeriod['id']);
        
        // Cek jika guru biasa mengakses tapi bukan BK
        if (!$access['is_admin'] && empty($access['classrooms'])) {
            return redirect()->to('/dashboard')->with('error', 'Akses dibatasi hanya untuk Guru BK dengan kelas binaan aktif.');
        }

        $db = \Config\Database::connect();
        
        // Ambil Semua Violators (siswa dengan poin tertinggi di semester berjalan)
        $topViolators = $db->table('student_violations sv')
            ->select('s.id, s.full_name, s.nis, s.nisn, c.name as classroom_name, SUM(vr.points) as total_points')
            ->join('students s', 's.id = sv.student_id')
            ->join('violation_rules vr', 'vr.id = sv.rule_id')
            ->join('student_academic_histories h', 'h.student_id = s.id AND h.academic_period_id = sv.academic_period_id')
            ->join('classrooms c', 'c.id = h.classroom_id')
            ->where('sv.academic_period_id', $activePeriod['id'])
            ->groupBy('s.id')
            ->orderBy('total_points', 'DESC')
            ->get()->getResultArray();

        // Tambahkan info sanksi untuk top violators
        foreach ($topViolators as &$v) {
            $sanc = $this->sanctionModel->getActiveSanction($v['total_points']);
            $v['sanction'] = $sanc ? $sanc['action_title'] : 'Aman';
        }

        $data = [
            'title'        => 'Workspace Guru BK — Poin Pelanggaran',
            'activePeriod' => $activePeriod,
            'classrooms'   => $access['classrooms'],
            'topViolators' => $topViolators,
            'is_admin'     => $access['is_admin'],
        ];

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

    public function classroom($classroomId)
    {
        $activePeriod = $this->periodModel->getActive();
        if (!$activePeriod) return redirect()->to('/bk/violations')->with('error', 'Tidak ada semester aktif.');

        $access = $this->getTeacherAndClasses($activePeriod['id']);
        
        // Validasi kepemilikan kelas binaan (kecuali Admin)
        $hasAccess = false;
        foreach ($access['classrooms'] as $c) {
            if ($c['id'] == $classroomId) {
                $hasAccess = true;
                break;
            }
        }
        if (!$access['is_admin'] && !$hasAccess) {
            return redirect()->to('/bk/violations')->with('error', 'Akses ditolak. Kelas ini bukan kelas binaan Anda.');
        }

        $db = \Config\Database::connect();
        
        // Ambil nama kelas
        $classInfo = $db->table('classrooms')->where('id', $classroomId)->get()->getRowArray();
        
        // Ambil semua siswa di kelas ini beserta total poin pelanggarannya di semester berjalan
        $students = $db->table('student_academic_histories h')
            ->select('s.id, s.full_name, s.nis, s.nisn')
            ->join('students s', 's.id = h.student_id')
            ->where('h.classroom_id', $classroomId)
            ->where('h.academic_period_id', $activePeriod['id'])
            ->where('s.deleted_at', null)
            ->orderBy('s.full_name', 'ASC')
            ->get()->getResultArray();

        foreach ($students as &$stu) {
            $points = $this->violationModel->getAccumulatedPoints($stu['id'], $activePeriod['id']);
            $stu['total_points'] = $points;
            $sanc = $this->sanctionModel->getActiveSanction($points);
            $stu['sanction'] = $sanc ? $sanc['action_title'] : 'Aman';
            $stu['violations'] = $this->violationModel->getLogsByStudent($stu['id'], $activePeriod['id']);
        }

        $data = [
            'title'        => 'Detail Pelanggaran Kelas ' . $classInfo['name'],
            'classroom'    => $classInfo,
            'students'     => $students,
            'rules'        => $this->ruleModel->getAllWithCategory(),
            'activePeriod' => $activePeriod,
        ];

        return view('bk/classroom', $data);
    }

    public function store()
    {
        $activePeriod = $this->periodModel->getActive();
        if (!$activePeriod) return redirect()->back()->with('error', 'Tidak ada semester aktif.');

        $rules = [
            'student_id'   => 'required|is_natural_no_zero',
            'rule_id'      => 'required|is_natural_no_zero',
            'date'         => 'required|valid_date[Y-m-d]',
            'notes'        => 'permit_empty|max_length[500]',
        ];

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

        $studentId = $this->request->getPost('student_id');
        $ruleId    = $this->request->getPost('rule_id');

        $userId = session()->get('user_id');
        $role   = session()->get('user_role');
        $db     = \Config\Database::connect();

        if (!in_array($role, ['superadmin', 'admin'])) {
            $teacher = $db->table('teachers')->where('user_id', $userId)->get()->getRowArray();
            if (!$teacher) return redirect()->back()->with('error', 'Guru tidak ditemukan.');

            $history = $db->table('student_academic_histories')
                ->where('student_id', $studentId)
                ->where('academic_period_id', $activePeriod['id'])
                ->get()->getRowArray();

            if (!$history) return redirect()->back()->with('error', 'Siswa tidak terdaftar di kelas aktif.');

            $assigned = $db->table('bk_assignments')
                ->where('teacher_id', $teacher['id'])
                ->where('classroom_id', $history['classroom_id'])
                ->where('academic_period_id', $activePeriod['id'])
                ->countAllResults();

            if ($assigned == 0) {
                return redirect()->back()->with('error', 'Anda tidak memiliki wewenang mencatat pelanggaran untuk siswa kelas ini.');
            }
        }

        $this->violationModel->insert([
            'student_id'         => $studentId,
            'rule_id'            => $ruleId,
            'date'               => $this->request->getPost('date'),
            'notes'              => trim($this->request->getPost('notes') ?? ''),
            'recorded_by'        => session()->get('user_id'),
            'academic_period_id' => $activePeriod['id'],
        ]);

        return redirect()->back()->with('success', 'Pelanggaran berhasil dicatat!');
    }

    public function delete($id)
    {
        $violation = $this->violationModel->find($id);
        if (!$violation) {
            return redirect()->back()->with('error', 'Catatan pelanggaran tidak ditemukan.');
        }

        $role   = session()->get('user_role');
        $userId = session()->get('user_id');
        $db     = \Config\Database::connect();

        if (!in_array($role, ['superadmin', 'admin'])) {
            $teacher = $db->table('teachers')->where('user_id', $userId)->get()->getRowArray();
            
            $history = $db->table('student_academic_histories')
                ->where('student_id', $violation['student_id'])
                ->where('academic_period_id', $violation['academic_period_id'])
                ->get()->getRowArray();

            $assigned = 0;
            if ($teacher && $history) {
                $assigned = $db->table('bk_assignments')
                    ->where('teacher_id', $teacher['id'])
                    ->where('classroom_id', $history['classroom_id'])
                    ->where('academic_period_id', $violation['academic_period_id'])
                    ->countAllResults();
            }

            if ($assigned == 0 && $violation['recorded_by'] != $userId) {
                return redirect()->back()->with('error', 'Anda tidak memiliki wewenang untuk menghapus catatan pelanggaran ini.');
            }
        }

        $this->violationModel->delete($id);
        return redirect()->back()->with('success', 'Catatan pelanggaran berhasil dihapus!');
    }

    public function homeroomIndex()
    {
        $activePeriod = $this->periodModel->getActive();
        if (!$activePeriod) {
            return redirect()->to('/dashboard')->with('error', 'Tidak ada semester aktif.');
        }

        $userId = session()->get('user_id');
        $db     = \Config\Database::connect();

        // Cari data guru dari user_id yang sedang login
        $teacher = $db->table('teachers')
            ->where('user_id', $userId)
            ->get()->getRowArray();

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

        // Cari relasi wali kelas di tabel homeroom_assignments
        $assignment = $db->table('homeroom_assignments h')
            ->select('h.classroom_id, c.name as classroom_name')
            ->join('classrooms c', 'c.id = h.classroom_id')
            ->where('h.teacher_id', $teacher['id'])
            ->where('h.academic_period_id', $activePeriod['id'])
            ->get()->getRowArray();

        if (!$assignment) {
            return redirect()->to('/dashboard')->with('error', 'Anda tidak terdaftar sebagai wali kelas aktif di semester ini.');
        }

        $classroomId = $assignment['classroom_id'];

        // Ambil semua siswa di kelas ini beserta total poin pelanggarannya di semester berjalan
        $students = $db->table('student_academic_histories h')
            ->select('s.id, s.full_name, s.nis, s.nisn')
            ->join('students s', 's.id = h.student_id')
            ->where('h.classroom_id', $classroomId)
            ->where('h.academic_period_id', $activePeriod['id'])
            ->where('s.deleted_at', null)
            ->orderBy('s.full_name', 'ASC')
            ->get()->getResultArray();

        foreach ($students as &$stu) {
            $points = $this->violationModel->getAccumulatedPoints($stu['id'], $activePeriod['id']);
            $stu['total_points'] = $points;
            $sanc = $this->sanctionModel->getActiveSanction($points);
            $stu['sanction'] = $sanc ? $sanc['action_title'] : 'Aman';
            $stu['violations'] = $this->violationModel->getLogsByStudent($stu['id'], $activePeriod['id']);
        }

        $data = [
            'title'        => 'Rekap Pelanggaran Siswa Kelas ' . $assignment['classroom_name'],
            'classroom'    => $assignment,
            'students'     => $students,
            'activePeriod' => $activePeriod,
        ];

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