<?php

namespace App\Controllers\View;
use App\Controllers\BaseController;
use App\Models\StudentClassModel;
use App\Models\UserModel;
use App\Models\TeacherClassModel;
use App\Models\StudentModel;
use App\Models\TeacherModel;
use App\Models\ClassSectionModel;
use App\Models\ConfigurationModel;
use Config\Database;

class AssignmentController extends BaseController
{
    protected $userModel;
    protected $configModel;
    protected $semester;
    protected $schoolYear;
    protected $studentModel;
    protected $teacherClassModel;
    protected $studentClassModel;
    protected $classSectionModel;

    public function __construct()
    {
        helper('auth');
        // Load models
        $this->userModel = new UserModel();
        $this->configModel = new ConfigurationModel();
        $this->studentModel       = new StudentModel();
        $this->classSectionModel = new ClassSectionModel();
        $this->teacherClassModel  = new TeacherClassModel();
        $this->studentClassModel  = new StudentClassModel();

        $this->semester = $this->configModel->getConfig('semester');
        $this->schoolYear = $this->configModel->getConfig('school_year');
        
    }

    public function index()
    {
        $data = [
            'classSections' => []
        ];

        // Apply school year filter (default to current config) but avoid semester filtering so the full year is visible
        $selectedSemester = (string)($this->request->getGet('semester') ?? $this->semester ?? '');
        $year = (string)($this->schoolYear ?? '');

        $this->applyPendingDistributionDraftsForEnrolledStudents($year);

        $tcQ = $this->teacherClassModel;
        if ($year !== '') {
            $tcQ = $tcQ->where('school_year', $year);
        }
        $teacherClassesAll = $tcQ->findAll();

        $scQ = $this->studentClassModel->active();
        if ($year !== '') {
            $scQ = $scQ->where('student_class.school_year', $year);
        }
        $studentClassesAll = $scQ->findAll();

    // Group teacher and student classes by section
    $teacherBySection = [];
    foreach ($teacherClassesAll as $tc) {
        $teacherBySection[$tc['class_section_id']][] = $tc;
    }

    $studentsBySection = [];
    foreach ($studentClassesAll as $sc) {
        $studentsBySection[$sc['class_section_id']][] = $sc;
    }

    $allSectionIds = array_unique(array_merge(array_keys($teacherBySection), array_keys($studentsBySection)));

    foreach ($allSectionIds as $classSectionId) {
        $teacherClasses = $teacherBySection[$classSectionId] ?? [];
        $studentClasses = $studentsBySection[$classSectionId] ?? [];

        $hasTeacher  = !empty($teacherClasses);
        $hasStudents = !empty($studentClasses);

        if (!$hasTeacher && !$hasStudents) {
            continue;
        }

        $classSectionName = (string) ($this->classSectionModel->getClassSectionNameBySectionId($classSectionId) ?? '');

        $mainTeachers = [];
        $teacherAssistants = [];
        $sectionSemester = '';
        $sectionSchoolYear = '';
        $description = '';

        if ($hasTeacher) {
            foreach ($teacherClasses as $teacherClass) {
                $teacher = $this->userModel->find($teacherClass['teacher_id']);
                if (!$teacher) continue;

                $teacherName = trim(($teacher['firstname'] ?? '') . ' ' . ($teacher['lastname'] ?? ''));
                if ($teacherName === '') continue;

                if (($teacherClass['position'] ?? '') === 'main') {
                    $mainTeachers[] = $teacherName;
                } elseif (($teacherClass['position'] ?? '') === 'ta') {
                    $teacherAssistants[] = $teacherName;
                }

                if ($sectionSemester === '' && !empty($teacherClass['semester'])) {
                    $sectionSemester = (string)$teacherClass['semester'];
                }
                if ($sectionSchoolYear === '' && !empty($teacherClass['school_year'])) {
                    $sectionSchoolYear = (string)$teacherClass['school_year'];
                }
                if ($description === '' && !empty($teacherClass['description'])) {
                    $description = (string)$teacherClass['description'];
                }
            }
        }

        $students = [];
        $seenStudentIds = [];
        foreach ($studentClasses as $studentClass) {
            $sid = (int)($studentClass['student_id'] ?? 0);
            if ($sid <= 0 || isset($seenStudentIds[$sid])) {
                continue;
            }
            if ($sectionSemester === '' && !empty($studentClass['semester'])) {
                $sectionSemester = (string)$studentClass['semester'];
            }
            if ($sectionSchoolYear === '' && !empty($studentClass['school_year'])) {
                $sectionSchoolYear = (string)$studentClass['school_year'];
            }
            if ($description === '' && !empty($studentClass['description'])) {
                $description = (string)$studentClass['description'];
            }

            $student = $this->studentModel
                ->where('id', $studentClass['student_id'])
                ->where('is_active', 1)
                ->first();
            if (!$student) {
                continue;
            }

            $students[] = [
                'id'                 => (int)$student['id'],
                'firstname'           => esc($student['firstname']),
                'lastname'            => esc($student['lastname']),
                'age'                 => esc($student['age']),
                'gender'              => esc($student['gender']),
                'registration_grade'  => esc($student['registration_grade']),
                'photo_consent'       => esc($student['photo_consent'] ? 'Yes' : 'No'),
                'tuition_paid'        => esc($student['tuition_paid'] ? 'Yes' : 'No'),
                'school_id'           => esc($student['school_id']),
            ];
            $seenStudentIds[$sid] = true;
        }

        $sectionSemesterDisplay = $sectionSemester !== '' ? $sectionSemester : ((string)($this->semester ?? ''));
        $sectionSchoolYearDisplay = $sectionSchoolYear !== '' ? $sectionSchoolYear : ((string)($this->schoolYear ?? ''));
        $data['classSections'][] = [
            'class_section_id'   => $classSectionId,
            'class_section_name' => $classSectionName,
            'main_teachers'       => $mainTeachers,
            'teacher_assistants' => $teacherAssistants,
            'students'           => $students,
            'semester'           => $sectionSemesterDisplay,
            'school_year'        => $sectionSchoolYearDisplay,
            'description'        => $description,
        ];
    }

    $schoolYearsList = [];
        try {
            $db = Database::connect();
            $yearsQuery = $db->table('teacher_class')
                ->select('DISTINCT school_year', false)
                ->where('school_year IS NOT NULL', null, false)
            ->orderBy('school_year', 'DESC')
            ->get()
            ->getResultArray();
        foreach ($yearsQuery as $row) {
            $val = (string)($row['school_year'] ?? '');
            if ($val !== '' && !in_array($val, $schoolYearsList, true)) {
                $schoolYearsList[] = $val;
            }
        }
    } catch (\Throwable $e) {
        // ignore fallback below
    }
    if ($this->schoolYear !== null && $this->schoolYear !== '' && !in_array((string)$this->schoolYear, $schoolYearsList, true)) {
        array_unshift($schoolYearsList, (string)$this->schoolYear);
    }

    // Sort sections
    usort($data['classSections'], fn($a, $b) => strcmp((string) $a['class_section_name'], (string) $b['class_section_name']));

    $data['schoolYears'] = $schoolYearsList;
    $data['schoolYear'] = $year;
    $data['selectedYear'] = $year;
    $data['selectedSemester'] = $selectedSemester;

    return view('administrator/class_assignment', $data);
}

    private function applyPendingDistributionDraftsForEnrolledStudents(string $year): void
    {
        if ($year === '') {
            return;
        }

        try {
            $db = Database::connect();
            if (! $db->tableExists('student_section_distribution_drafts')) {
                return;
            }

            $rows = $db->table('student_section_distribution_drafts d')
                ->select('d.id, d.student_id, d.class_section_id')
                ->join(
                    'enrollments e',
                    'e.student_id = d.student_id AND e.school_year = d.school_year',
                    'inner'
                )
                ->where('d.school_year', $year)
                ->where('d.status', 'pending')
                ->whereIn('e.enrollment_status', ['payment pending', 'enrolled'])
                ->groupBy('d.id, d.student_id, d.class_section_id')
                ->get()
                ->getResultArray();

            if (empty($rows)) {
                return;
            }

            $now = utc_now();
            $updatedBy = (int)(session()->get('user_id') ?? 0) ?: null;

            $db->transStart();
            foreach ($rows as $row) {
                $studentId = (int)($row['student_id'] ?? 0);
                $sectionId = (int)($row['class_section_id'] ?? 0);
                if ($studentId <= 0 || $sectionId <= 0) {
                    continue;
                }

                $existing = $db->table('student_class')
                    ->select('id')
                    ->where('student_id', $studentId)
                    ->where('school_year', $year)
                    ->get()
                    ->getRowArray();

                $payload = [
                    'student_id'       => $studentId,
                    'class_section_id' => $sectionId,
                    'school_year'      => $year,
                    'updated_by'       => $updatedBy,
                    'updated_at'       => $now,
                ];

                if ($existing) {
                    $db->table('student_class')
                        ->where('id', (int)$existing['id'])
                        ->update($payload);
                } else {
                    $payload['created_at'] = $now;
                    $db->table('student_class')->insert($payload);
                }

                $db->table('enrollments')
                    ->where('student_id', $studentId)
                    ->where('school_year', $year)
                    ->whereIn('enrollment_status', ['payment pending', 'enrolled'])
                    ->update([
                        'class_section_id' => $sectionId,
                        'updated_at'       => $now,
                    ]);

                $db->table('student_section_distribution_drafts')
                    ->where('id', (int)$row['id'])
                    ->update([
                        'status'     => 'applied',
                        'applied_at' => $now,
                        'updated_at' => $now,
                    ]);
            }
            $db->transComplete();
        } catch (\Throwable $e) {
            log_message('error', 'applyPendingDistributionDraftsForEnrolledStudents failed: ' . $e->getMessage());
        }
    }



    public function save()
    {

        $data = [
            'student_id' => $this->request->getPost('student_id'),
            'class_section_id' => $this->request->getPost('class_section_id'),
            'semester' => $this->request->getPost('semester'),
            'school_year' => $this->request->getPost('school_year'),
            'description' => $this->request->getPost('description'),
            'updated_by' => session()->get('user_id'),
        ];

        $this->studentClassModel->save($data);

        return redirect()->to('/assignments')->with('message', 'Assignment saved successfully');
    }

    // API: JSON payload for Classes List page
    public function classAssignmentData()
    {
        $teacherClassesAll = $this->teacherClassModel->findAll();
        $studentClassesAll = $this->studentClassModel->findAll();

        // Group by section
        $teacherBySection = [];
        foreach ($teacherClassesAll as $tc) {
            $secId = (int)($tc['class_section_id'] ?? 0);
            if ($secId) $teacherBySection[$secId][] = $tc;
        }
        $studentsBySection = [];
        foreach ($studentClassesAll as $sc) {
            $secId = (int)($sc['class_section_id'] ?? 0);
            if ($secId) $studentsBySection[$secId][] = $sc;
        }

        $allSectionIds = array_values(array_unique(array_merge(array_keys($teacherBySection), array_keys($studentsBySection))));

        $classSections = [];

        foreach ($allSectionIds as $classSectionId) {
            $hasTeacher  = !empty($teacherBySection[$classSectionId]);
            $hasStudents = !empty($studentsBySection[$classSectionId]);
            if (!$hasTeacher && !$hasStudents) continue;

            $classSectionName = (string) ($this->classSectionModel->getClassSectionNameBySectionId($classSectionId) ?? '');

            $mainTeachers = [];
            $teacherAssistants = [];
            $semesterMeta = '';
            $schoolYearMeta = '';
            $descriptionMeta = '';

            if ($hasTeacher) {
                foreach ($teacherBySection[$classSectionId] as $teacherClass) {
                    $teacher = $this->userModel->find((int)$teacherClass['teacher_id']);
                    if ($teacher) {
                        $tname = trim(($teacher['firstname'] ?? '') . ' ' . ($teacher['lastname'] ?? ''));
                        if (($teacherClass['position'] ?? '') === 'main') {
                            $mainTeachers[] = $tname;
                        } elseif (($teacherClass['position'] ?? '') === 'ta') {
                            $teacherAssistants[] = $tname;
                        }
                    }
                    // assign meta (same for all rows in a section)
                    if ($semesterMeta === '' && !empty($teacherClass['semester'])) {
                        $semesterMeta = (string)$teacherClass['semester'];
                    }
                    if ($schoolYearMeta === '' && !empty($teacherClass['school_year'])) {
                        $schoolYearMeta = (string)$teacherClass['school_year'];
                    }
                    if ($descriptionMeta === '' && !empty($teacherClass['description'])) {
                        $descriptionMeta = (string)$teacherClass['description'];
                    }
                }
            }

            // Load students for the section
            $students = [];
            foreach ($this->studentClassModel->active()->where('student_class.class_section_id', $classSectionId)->findAll() as $studentClass) {
                $stu = $this->studentModel
                    ->where('id', (int)$studentClass['student_id'])
                    ->where('is_active', 1)
                    ->first();
                if (!$stu) continue;
                $students[] = [
                    'id'                  => (int)$stu['id'],
                    'firstname'           => (string)($stu['firstname'] ?? ''),
                    'lastname'            => (string)($stu['lastname'] ?? ''),
                    'age'                 => $stu['age'] ?? null,
                    'gender'              => (string)($stu['gender'] ?? ''),
                    'registration_grade'  => (string)($stu['registration_grade'] ?? ''),
                    'photo_consent'       => (bool)($stu['photo_consent'] ?? false),
                    'tuition_paid'        => (bool)($stu['tuition_paid'] ?? false),
                    'school_id'           => (string)($stu['school_id'] ?? ''),
                ];
            }

            $classSections[] = [
                'class_section_id'    => (int)$classSectionId,
                'class_section_name'  => $classSectionName,
                'main_teachers'       => array_values(array_unique($mainTeachers)),
                'teacher_assistants'  => array_values(array_unique($teacherAssistants)),
                'students'            => $students,
                'semester'            => $semesterMeta ?: (string)$this->semester,
                'school_year'         => $schoolYearMeta ?: (string)$this->schoolYear,
                'description'         => $descriptionMeta,
            ];
        }

        // Sort by class_section_name
        usort($classSections, fn($a, $b) => strcmp((string)($a['class_section_name'] ?? ''), (string)($b['class_section_name'] ?? '')));

        return $this->response->setJSON([
            'classSections' => $classSections,
            'csrfHash'      => csrf_hash(),
            'semester'      => (string)$this->semester,
            'school_year'   => (string)$this->schoolYear,
        ]);
    }
}
