<?php

namespace App\Http\Controllers\Teacher;

use App\Http\Controllers\Controller;
use App\Models\Mark;
use App\Models\Exam;
use App\Models\Stream;
use App\Models\Subject;
use App\Models\Student;
use App\Models\Assignment;
use App\Models\Attendance;
use App\Services\GradingService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

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

    public function dashboard()
    {
        $teacher = auth()->user()->teacher;
        $streams = $teacher->subjectStreams()->with(['stream.schoolClass', 'subject'])->get();
        $assignments = Assignment::where('teacher_id', $teacher->id)->latest()->limit(5)->get();
        return view('teacher.dashboard', compact('teacher', 'streams', 'assignments'));
    }

    public function timetable()
    {
        $teacher = auth()->user()->teacher;
        $timetable = $teacher->timetables()->with(['stream.schoolClass', 'subject'])
            ->orderBy('day_of_week')->orderBy('start_time')->get()
            ->groupBy('day_of_week');
        return view('teacher.timetable', compact('timetable'));
    }

    public function marksEntry(Request $request)
    {
        $teacher = auth()->user()->teacher;
        $exams = Exam::where('school_id', auth()->user()->school_id)
            ->whereHas('term', fn($q) => $q->where('is_current', true))->get();
        $streams = $teacher->subjectStreams()->with(['stream.schoolClass', 'subject'])->get();

        $students = collect();
        $selectedExam = $selectedStream = $selectedSubject = null;

        if ($request->filled(['exam_id', 'stream_id', 'subject_id'])) {
            $selectedExam    = Exam::findOrFail($request->exam_id);
            $selectedStream  = Stream::findOrFail($request->stream_id);
            $selectedSubject = Subject::findOrFail($request->subject_id);

            $students = Student::where('stream_id', $request->stream_id)
                ->where('status', 'active')
                ->with(['user', 'marks' => fn($q) => $q->where('exam_id', $request->exam_id)->where('subject_id', $request->subject_id)])
                ->get();
        }

        return view('teacher.marks-entry', compact('exams', 'streams', 'students', 'selectedExam', 'selectedStream', 'selectedSubject'));
    }

    public function saveMarks(Request $request)
    {
        $request->validate([
            'exam_id'    => 'required|exists:exams,id',
            'stream_id'  => 'required|exists:streams,id',
            'subject_id' => 'required|exists:subjects,id',
            'marks'      => 'required|array',
            'marks.*'    => 'nullable|numeric|min:0|max:100',
        ]);

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

    public function attendance(Request $request)
    {
        $teacher = auth()->user()->teacher;
        $stream = $teacher->subjectStreams()->first()?->stream;
        if (!$stream) return back()->with('error', 'No stream assigned.');

        $date = $request->date ?? today()->toDateString();
        $students = Student::where('stream_id', $stream->id)->where('status', 'active')
            ->with(['user', 'attendances' => fn($q) => $q->where('date', $date)])->get();

        return view('teacher.attendance', compact('stream', 'students', 'date'));
    }

    public function storeAssignment(Request $request)
    {
        $data = $request->validate([
            'title'       => 'required|string|max:200',
            'description' => 'nullable|string',
            'subject_id'  => 'required|exists:subjects,id',
            'stream_id'   => 'required|exists:streams,id',
            'due_date'    => 'required|date|after:today',
            'total_marks' => 'required|numeric|min:1',
            'file'        => 'nullable|file|mimes:pdf,doc,docx|max:5120',
        ]);

        $filePath = null;
        if ($request->hasFile('file')) {
            $filePath = $request->file('file')->store('assignments', 'public');
        }

        Assignment::create(array_merge($data, [
            'teacher_id' => auth()->user()->teacher->id,
            'file_path'  => $filePath,
        ]));

        return back()->with('success', 'Assignment uploaded.');
    }
}
