<?php

namespace App\Http\Controllers;

use App\Models\Exam;
use App\Models\ExamPaper;
use App\Models\Mark;
use App\Models\SchoolClass;
use App\Models\Student;
use App\Services\ResultService;
use Illuminate\Http\Request;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\View\View;

class ResultController extends Controller implements HasMiddleware
{
    public function __construct(private ResultService $results)
    {
    }

    public static function middleware(): array
    {
        return [new Middleware('can:exams.view')];
    }

    /** Individual student result card. */
    public function card(Request $request): View
    {
        $examId = $request->integer('exam_id') ?: null;
        $studentId = $request->integer('student_id') ?: null;

        $exam = $examId ? Exam::find($examId) : null;
        $student = $studentId ? Student::find($studentId) : null;
        $result = null;
        $position = null;

        if ($exam && $student) {
            $result = $this->results->studentResult($exam, $student);
            $position = $this->results->classResults($exam, $student->class_id)
                ->firstWhere(fn ($r) => $r['student']->id === $student->id)['position'] ?? null;
        }

        $grades = collect();
        $classSize = null;
        if ($exam && $student) {
            $grades = \App\Models\GradeScale::where('branch_id', $exam->branch_id)
                ->orderByDesc('min_percentage')->get();
            $classSize = $this->results->classResults($exam, $student->class_id)->count();
        }

        return view('exams.results.card', [
            'exams' => Exam::orderByDesc('id')->get(),
            'students' => Student::active()->orderBy('name')->get(),
            'exam' => $exam, 'student' => $student, 'result' => $result, 'position' => $position,
            'grades' => $grades, 'classSize' => $classSize,
        ]);
    }

    /** Class gazette — all students × subjects. */
    public function gazette(Request $request): View
    {
        $examId = $request->integer('exam_id') ?: null;
        $classId = $request->integer('class_id') ?: null;

        $exam = $examId ? Exam::find($examId) : null;
        $papers = collect();
        $rows = collect();

        if ($exam && $classId) {
            $papers = ExamPaper::where('exam_id', $exam->id)->where('class_id', $classId)->with('subject')->get();
            $marks = Mark::where('exam_id', $exam->id)
                ->whereHas('student', fn ($q) => $q->where('class_id', $classId))
                ->get()->groupBy('student_id');

            $rows = $this->results->classResults($exam, $classId)->map(function ($r) use ($marks) {
                $r['subject_marks'] = $marks->get($r['student']->id, collect())->keyBy('subject_id');

                return $r;
            })->sortBy('position')->values();
        }

        return view('exams.results.gazette', [
            'exams' => Exam::orderByDesc('id')->get(),
            'classes' => SchoolClass::active()->orderBy('level')->get(),
            'exam' => $exam, 'classId' => $classId, 'papers' => $papers, 'rows' => $rows,
        ]);
    }

    /** Position holders + subject analysis for a class. */
    public function positions(Request $request): View
    {
        $examId = $request->integer('exam_id') ?: null;
        $classId = $request->integer('class_id') ?: null;

        $exam = $examId ? Exam::find($examId) : null;
        $holders = collect();
        $analysis = collect();

        if ($exam && $classId) {
            $holders = $this->results->positionHolders($exam, $classId, 5);
            $analysis = $this->results->subjectAnalysis($exam, $classId);
        }

        return view('exams.results.positions', [
            'exams' => Exam::orderByDesc('id')->get(),
            'classes' => SchoolClass::active()->orderBy('level')->get(),
            'exam' => $exam, 'classId' => $classId, 'holders' => $holders, 'analysis' => $analysis,
        ]);
    }
}
