<?php

namespace App\Http\Controllers\Admin\School;

use App\Http\Controllers\Admin\PageController;
use App\Models\GradebookEntry;
use App\Models\SchoolClass;
use App\Models\Subject;
use App\Models\Term;
use App\Services\School\GradebookService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class GradeController extends PageController
{
    public function __construct(
        private readonly GradebookService $gradebookService,
    ) {}

    public function index(): View
    {
        $entries = GradebookEntry::query()
            ->with(['student', 'assessment.subject'])
            ->latest()
            ->paginate(30);

        return $this->page('admin.grades.index', [
            'crumbTitle' => 'Grades',
            'crumbSub' => 'Marksheets & reports',
            'entries' => $entries,
        ]);
    }

    public function entry(Request $request): View
    {
        $classId = $request->integer('class_id') ?: null;
        $subjectId = $request->integer('subject_id') ?: null;
        $termId = $request->integer('term_id') ?: Term::query()->where('is_current', true)->value('id');
        $assessmentType = $request->input('assessment_type');
        $maxScore = $request->input('max_score', 100);
        $title = $request->input('title');

        $context = null;

        if ($classId && $subjectId && $termId && $assessmentType) {
            $context = $this->gradebookService->loadEntryContext(
                $classId,
                $subjectId,
                $termId,
                $assessmentType,
                $title,
            );
        }

        return $this->page('admin.grades.entry', [
            'crumbTitle' => 'Grades',
            'crumbSub' => 'Enter assessment scores',
            'classes' => SchoolClass::query()->orderBy('name')->get(),
            'subjects' => Subject::query()->where('is_active', true)->orderBy('name')->get(),
            'terms' => Term::query()->with('academicYear')->orderByDesc('starts_on')->get(),
            'assessmentTypes' => ['exam', 'quiz', 'homework', 'project', 'test'],
            'classId' => $classId,
            'subjectId' => $subjectId,
            'termId' => $termId,
            'assessmentType' => $assessmentType,
            'maxScore' => $maxScore,
            'title' => $title,
            'context' => $context,
        ]);
    }

    public function storeEntry(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'class_id' => ['required', 'exists:classes,id'],
            'subject_id' => ['required', 'exists:subjects,id'],
            'term_id' => ['required', 'exists:terms,id'],
            'assessment_type' => ['required', 'string', 'max:50'],
            'max_score' => ['required', 'numeric', 'min:1', 'max:1000'],
            'title' => ['nullable', 'string', 'max:255'],
            'assessment_date' => ['nullable', 'date'],
            'records' => ['required', 'array', 'min:1'],
            'records.*.student_id' => ['required', 'exists:students,id'],
            'records.*.score' => ['nullable', 'numeric', 'min:0'],
            'records.*.remarks' => ['nullable', 'string', 'max:255'],
        ]);

        foreach ($validated['records'] as $index => $row) {
            if (isset($row['score']) && $row['score'] !== null && $row['score'] !== '') {
                $request->validate([
                    "records.{$index}.score" => ['numeric', 'max:'.$validated['max_score']],
                ]);
            }
        }

        $assessment = $this->gradebookService->findOrCreateAssessment([
            'class_id' => $validated['class_id'],
            'subject_id' => $validated['subject_id'],
            'term_id' => $validated['term_id'],
            'assessment_type' => $validated['assessment_type'],
            'max_score' => $validated['max_score'],
            'title' => $validated['title'] ?? null,
            'assessment_date' => $validated['assessment_date'] ?? null,
            'created_by' => auth()->user()?->staff_id,
        ]);

        $saved = $this->gradebookService->saveScores(
            $assessment,
            $validated['records'],
            auth()->user()?->staff_id,
        );

        return $this->redirectWithSuccess(
            'school.grades.index',
            "Saved {$saved} score(s) for {$assessment->title}.",
        );
    }
}
