<?php

namespace Modules\ExamPlan\Services;

use App\Models\StudentRecord;
use App\SmExamSchedule;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;

class AdmitCardSubjectService
{
    public function forRecord(StudentRecord $record, $examTypeId)
    {
        $schoolId = $record->school_id ?: (Auth::check() ? Auth::user()->school_id : null);
        $academicId = $record->academic_id ?: (function_exists('getAcademicId') ? getAcademicId() : null);

        if (function_exists('moduleStatusCheck') && moduleStatusCheck('University')) {
            return $this->forUniversity(
                $record->un_semester_label_id,
                $record->un_section_id,
                $examTypeId,
                $schoolId,
                $record->un_academic_id ?: $academicId
            );
        }

        return $this->forClassSection(
            $record->class_id,
            $record->section_id,
            $examTypeId,
            $schoolId,
            $academicId
        );
    }

    public function forClassSection($classId, $sectionId, $examTypeId, $schoolId, $academicId)
    {
        $key = $this->classSectionKey($classId, $sectionId, $examTypeId, $schoolId, $academicId);

        return Cache::remember($key, now()->addMinutes(30), function () use ($classId, $sectionId, $examTypeId, $schoolId, $academicId) {
            return SmExamSchedule::with('subject')
                ->where('class_id', $classId)
                ->where('section_id', $sectionId)
                ->where('exam_term_id', $examTypeId)
                ->where('school_id', $schoolId)
                ->where('academic_id', $academicId)
                ->orderBy('date', 'ASC')
                ->get()
                ->map(function ($schedule) {
                    return $this->formatScheduleRow($schedule);
                });
        });
    }

    public function forUniversity($semesterLabelId, $sectionId, $examTypeId, $schoolId, $academicId)
    {
        $key = $this->universityKey($semesterLabelId, $sectionId, $examTypeId, $schoolId, $academicId);

        return Cache::remember($key, now()->addMinutes(30), function () use ($semesterLabelId, $sectionId, $examTypeId, $schoolId, $academicId) {
            return SmExamSchedule::with('subject')
                ->where('un_semester_label_id', $semesterLabelId)
                ->where('un_section_id', $sectionId)
                ->where('exam_term_id', $examTypeId)
                ->where('school_id', $schoolId)
                ->where('academic_id', $academicId)
                ->orderBy('date', 'ASC')
                ->get()
                ->map(function ($schedule) {
                    return $this->formatScheduleRow($schedule);
                });
        });
    }

    public function forgetForClassSection($classId, $sectionId, $examTypeId, $schoolId, $academicId)
    {
        Cache::forget($this->classSectionKey($classId, $sectionId, $examTypeId, $schoolId, $academicId));
    }

    public function forgetForUniversity($semesterLabelId, $sectionId, $examTypeId, $schoolId, $academicId)
    {
        Cache::forget($this->universityKey($semesterLabelId, $sectionId, $examTypeId, $schoolId, $academicId));
    }

    private function classSectionKey($classId, $sectionId, $examTypeId, $schoolId, $academicId)
    {
        return "admit-card-subjects:school:{$schoolId}:academic:{$academicId}:exam:{$examTypeId}:class:{$classId}:section:{$sectionId}";
    }

    private function universityKey($semesterLabelId, $sectionId, $examTypeId, $schoolId, $academicId)
    {
        return "admit-card-subjects:school:{$schoolId}:un-academic:{$academicId}:exam:{$examTypeId}:semester-label:{$semesterLabelId}:section:{$sectionId}";
    }

    private function formatScheduleRow(SmExamSchedule $schedule)
    {
        $subject = $schedule->subject;

        return (object) [
            'subject_code' => $subject->subject_code ?? $subject->code ?? '',
            'subject_name' => $subject->subject_name ?? $subject->name ?? '',
            'exam_date' => $schedule->date,
        ];
    }
}
