<?php

namespace App\Http\Controllers\Admin\Manage;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Manage\CourseRegistrationRequest;
use App\Http\Requests\Admin\Manage\RejectCourseRegistrationRequest;
use App\Http\Requests\PaginatedRequest;
use App\Models\CourseRegistrationSubmission;
use App\Models\Student;
use App\Services\Admin\Manage\CourseClassService;
use App\Services\Admin\Manage\CourseRegistrationService;
use App\Services\Admin\Master\AcademicTermService;
use App\Services\Admin\Users\StudentService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class CourseRegistrationController extends Controller
{
    public function __construct(
        private readonly CourseRegistrationService $service,
        private readonly StudentService $studentService,
        private readonly AcademicTermService $academicTermService,
        private readonly CourseClassService $courseClassService,
    ) {}

    public function index(PaginatedRequest $request): Response
    {
        return Inertia::render('admin/manage/course-registrations/index', [
            'registrations' => $this->service->paginated(
                ...$request->validatedWithDefaults(),
                status: $request->validated('status'),
                academicTermId: $request->validated('academic_term_id'),
            ),
            'students' => $this->studentService->getAllForSelect(),
            'academicTerms' => $this->academicTermService->getAllForSelect(),
            'courseClasses' => $this->courseClassService->getAllForSelect(),
            'filters' => $request->only(['status', 'academic_term_id']),
        ]);
    }

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

        $term = $this->academicTermService->getActive();
        $payment = $term ? $this->service->paymentStatus($student, $term) : null;
        $activeSubmission = $term ? $this->service->currentSubmission($student, $term) : null;

        return Inertia::render('student/course-registrations/index', [
            'academicTerm' => $term,
            'payment' => $payment,
            'canSubmit' => $this->service->canSubmit($activeSubmission),
            'activeSubmission' => $activeSubmission,
            'submissions' => $this->service->submissionsFor($student),
        ]);
    }

    public function create(Request $request): Response|RedirectResponse
    {
        $student = $this->currentStudent($request);

        $student->load(['user.profile', 'department', 'academicAdvisor.user.profile']);

        $term = $this->academicTermService->getActive();
        $payment = $term ? $this->service->paymentStatus($student, $term) : null;
        $submission = $term ? $this->service->currentSubmission($student, $term) : null;

        if (! $term || ! $payment['is_paid'] || ! $this->service->canSubmit($submission)) {
            return to_route('student.course-registrations.index');
        }

        return Inertia::render('student/course-registrations/create', [
            'student' => $student,
            'academicTerm' => $term,
            'submission' => $submission,
            'availableCourses' => $this->service->availableCourseClasses($student, $term),
        ]);
    }

    public function show(Request $request, CourseRegistrationSubmission $submission): Response
    {
        if ($request->routeIs('student.*')) {
            $student = $this->currentStudent($request);

            abort_if($submission->student_id !== $student->id, 403);

            return Inertia::render('student/course-registrations/show', [
                'submission' => $this->service->withDetails($submission),
            ]);
        }

        return Inertia::render('admin/manage/course-registrations/show', [
            'submission' => $this->service->withDetails($submission),
        ]);
    }

    public function store(CourseRegistrationRequest $request): RedirectResponse
    {
        if ($request->routeIs('student.*')) {
            $student = $this->currentStudent($request);
            $term = $this->academicTermService->getActive();

            $submission = $this->service->sign(
                $student,
                $term,
                $request->validated('course_class_ids'),
                $request->file('signature'),
            );

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

            return to_route('student.course-registrations.show', $submission);
        }

        $this->service->create($request->validated());

        Inertia::flash('toast', ['type' => 'success', 'message' => 'Registrasi KRS berhasil ditambahkan.']);

        return to_route('admin.manage.course-registrations.index');
    }

    public function approve(CourseRegistrationSubmission $submission): RedirectResponse
    {
        $this->service->approve($submission);

        return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil disetujui.'])->back();
    }

    public function reject(RejectCourseRegistrationRequest $request, CourseRegistrationSubmission $submission): RedirectResponse
    {
        $this->service->reject($submission, $request->validated('reason'));

        return Inertia::flash('toast', ['type' => 'success', 'message' => 'KRS berhasil ditolak.'])->back();
    }

    private function currentStudent(Request $request): Student
    {
        $student = $request->user()->student;

        abort_if(! $student, 403);

        return $student;
    }
}
