<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Exam;
use App\Models\Mark;
use App\Models\Stream;
use App\Models\Subject;
use App\Models\Student;
use App\Services\GradingService;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Request;

class ExamController extends Controller
{
    public function __construct(private GradingService $grading) {}

    public function index()
    {
        $schoolId = auth()->user()->school_id;
        $exams = Exam::where('school_id', $schoolId)->with('term')->latest()->paginate(15);
        return view('admin.exams.index', compact('exams'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'name'       => 'required|string|max:100',
            'type'       => 'required|in:cat,midterm,endterm,mock,kcse',
            'term_id'    => 'required|exists:terms,id',
            'weight'     => 'required|numeric|min:1|max:100',
            'start_date' => 'nullable|date',
            'end_date'   => 'nullable|date|after_or_equal:start_date',
        ]);

        $exam = Exam::create(array_merge($data, ['school_id' => auth()->user()->school_id]));
        return redirect()->route('admin.exams.index')->with('success', 'Exam created.');
    }

    public function marksEntry(Exam $exam, Stream $stream, Subject $subject)
    {
        $students = Student::where('stream_id', $stream->id)
            ->where('status', 'active')
            ->with(['user', 'marks' => fn($q) => $q->where('exam_id', $exam->id)->where('subject_id', $subject->id)])
            ->get();

        return view('admin.exams.marks-entry', compact('exam', 'stream', 'subject', 'students'));
    }

    public function saveMarks(Request $request, Exam $exam, Stream $stream, Subject $subject)
    {
        $request->validate(['marks' => 'required|array', 'marks.*' => 'nullable|numeric|min:0|max:100']);

        $count = $this->grading->saveMarks($request->marks, $exam->id, $subject->id, auth()->id());
        return back()->with('success', "{$count} marks saved.");
    }

    public function results(Exam $exam, Stream $stream)
    {
        $results = $this->grading->getStreamResults($stream->id, $exam->id);
        $subjects = Subject::where('school_id', auth()->user()->school_id)->get();
        return view('admin.exams.results', compact('exam', 'stream', 'results', 'subjects'));
    }

    public function reportCard(Exam $exam, Student $student)
    {
        $marks = Mark::with('subject')
            ->where('student_id', $student->id)
            ->where('exam_id', $exam->id)
            ->get();

        $totalPoints = $marks->sum('points');
        $meanGrade = $marks->count() > 0 ? $this->grading->pointsToGrade($totalPoints / $marks->count()) : 'N/A';

        $pdf = Pdf::loadView('pdf.report-card', compact('student', 'exam', 'marks', 'totalPoints', 'meanGrade'));
        return $pdf->download("report-card-{$student->admission_no}.pdf");
    }

    public function publish(Exam $exam)
    {
        $exam->update(['is_published' => true]);
        return back()->with('success', 'Results published.');
    }
}
