<?php

namespace App\Http\Controllers\Admin\AcademicClasses;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\AcademicClasses\AttendanceStoreRequest;
use App\Models\CourseClass;
use App\Services\Admin\AcademicClasses\AttendanceService;
use App\Services\Admin\Master\AcademicTermService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class AttendanceController extends Controller
{
    public function __construct(
        private readonly AttendanceService $service,
        private readonly AcademicTermService $academicTermService,
    ) {}

    public function index(Request $request): Response
    {
        $academicTermId = $request->has('academic_term_id')
            ? $request->integer('academic_term_id')
            : $this->academicTermService->getActive()?->id;

        return Inertia::render('admin/academic-classes/attendances/index', [
            'courseClasses' => $this->service->courseClassesForUser($request->user(), $academicTermId),
            'academicTerms' => $this->academicTermService->getAllForSelect(),
            'filters' => [
                'academic_term_id' => $academicTermId ? (string) $academicTermId : null,
            ],
        ]);
    }

    public function mine(Request $request): Response
    {
        $student = $request->user()->student;

        abort_if(! $student, 403);

        return Inertia::render('admin/academic-classes/attendances/mine', [
            'summaries' => $this->service->forStudent($student),
        ]);
    }

    public function show(CourseClass $courseClass): Response
    {
        $this->abortUnlessLecturerOwnsClass($courseClass);

        $courseClass->load(['course', 'academicTerm']);

        return Inertia::render('admin/academic-classes/attendances/course-class', [
            'courseClass' => $courseClass,
            'sessions' => $this->service->sessionsForClass($courseClass),
            'nextMeetingNumber' => $this->service->nextMeetingNumber($courseClass),
        ]);
    }

    public function session(CourseClass $courseClass, int $meetingNumber): Response
    {
        $this->abortUnlessLecturerOwnsClass($courseClass);

        $courseClass->load('course');
        $data = $this->service->session($courseClass, $meetingNumber);

        return Inertia::render('admin/academic-classes/attendances/session', [
            'courseClass' => $courseClass,
            'meetingNumber' => $meetingNumber,
            'roster' => $data['roster'],
            'date' => $data['date'],
        ]);
    }

    public function store(AttendanceStoreRequest $request, CourseClass $courseClass, int $meetingNumber): RedirectResponse
    {
        $this->service->saveSession($courseClass->id, $meetingNumber, $request->validated('date'), $request->validated('records'));

        Inertia::flash('toast', ['type' => 'success', 'message' => 'Kehadiran berhasil disimpan.']);

        return to_route('admin.academic-classes.attendances.session', [$courseClass->id, $meetingNumber]);
    }

    public function destroy(CourseClass $courseClass, int $meetingNumber): RedirectResponse
    {
        $this->abortUnlessLecturerOwnsClass($courseClass);

        $this->service->deleteSession($courseClass->id, $meetingNumber);

        Inertia::flash('toast', ['type' => 'success', 'message' => 'Sesi kehadiran berhasil dihapus.']);

        return to_route('admin.academic-classes.attendances.show', [$courseClass->id]);
    }

    /**
     * A dosen may only take or manage attendance for classes they lecture.
     */
    private function abortUnlessLecturerOwnsClass(CourseClass $courseClass): void
    {
        $user = request()->user();

        abort_if(
            $user->hasRole('dosen') && $courseClass->lecturer_id !== $user->lecturer?->id,
            403,
        );
    }
}
