<?php

namespace App\Services\Admin\AcademicClasses;

use App\Enums\RegistrationStatus;
use App\Models\CourseClass;
use App\Models\Schedule;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;

class ScheduleService
{
    public function all(User $user, ?int $academicTermId = null, ?int $departmentId = null, ?int $semesterNumber = null): Collection
    {
        return Schedule::query()
            ->select(['id', 'course_class_id', 'day_of_week', 'start_time', 'end_time', 'room', 'online_link'])
            ->with([
                'courseClass:id,course_id,lecturer_id,academic_term_id,method',
                'courseClass.course:id,code,name,department_id',
                'courseClass.course.department:id,name',
                'courseClass.lecturer:id,user_id,lecturer_number',
                'courseClass.lecturer.user:id,username',
                'courseClass.lecturer.user.profile:id,user_id,full_name',
            ])
            ->whereHas('courseClass', function ($q) use ($user, $academicTermId, $departmentId, $semesterNumber) {
                $q->when($academicTermId, fn ($q) => $q->where('academic_term_id', $academicTermId))
                    ->when($departmentId, fn ($q) => $q->whereHas('course', fn ($q) => $q->where('department_id', $departmentId)))
                    ->when($semesterNumber, fn ($q) => $q->whereHas('course', fn ($q) => $q->where('semester_number', $semesterNumber)))
                    ->when($user->hasRole('mahasiswa'), fn ($q) => $q->whereHas('registrations', function ($q) use ($user) {
                        $q->where('student_id', $user->student?->id)
                            ->whereHas('submission', fn ($q) => $q->where('status', RegistrationStatus::Approved));
                    }))
                    ->when($user->hasRole('dosen'), fn ($q) => $q->where('lecturer_id', $user->lecturer?->id));
            })
            ->orderBy('start_time')
            ->get();
    }

    /**
     * Course classes for the schedule form's picker, grouped by department and
     * semester and ordered alphabetically to match the course-class picker
     * pattern used elsewhere.
     */
    public function courseClassOptions(): Collection
    {
        return CourseClass::query()
            ->select(['course_classes.id', 'course_classes.course_id', 'course_classes.lecturer_id', 'course_classes.academic_term_id'])
            ->join('courses', 'courses.id', '=', 'course_classes.course_id')
            ->join('departments', 'departments.id', '=', 'courses.department_id')
            ->with([
                'course:id,code,name,department_id,semester_number',
                'course.department:id,name',
                'lecturer:id,user_id,lecturer_number',
                'lecturer.user:id,username',
                'lecturer.user.profile:id,user_id,full_name',
                'academicTerm:id,academic_year,semester,start_date,end_date',
            ])
            ->orderBy('departments.name')
            ->orderBy('courses.semester_number')
            ->orderBy('courses.name')
            ->get();
    }

    public function create(array $data): Schedule
    {
        return Schedule::create([
            'course_class_id' => $data['course_class_id'],
            'day_of_week' => $data['day_of_week'],
            'start_time' => $data['start_time'],
            'end_time' => $data['end_time'],
            'room' => $data['room'] ?? null,
            'online_link' => $data['online_link'] ?? null,
        ]);
    }

    public function update(Schedule $schedule, array $data): Schedule
    {
        $schedule->course_class_id = $data['course_class_id'];
        $schedule->day_of_week = $data['day_of_week'];
        $schedule->start_time = $data['start_time'];
        $schedule->end_time = $data['end_time'];
        $schedule->room = $data['room'] ?? null;
        $schedule->online_link = $data['online_link'] ?? null;
        $schedule->update();

        return $schedule;
    }

    public function delete(Schedule $schedule): bool
    {
        return $schedule->delete();
    }
}
