<?php

namespace App\Http\Controllers\Admin\School;

use App\Http\Controllers\Admin\PageController;
use App\Models\Attendance;
use App\Models\AttendanceRecord;
use App\Models\SchoolClass;
use App\Models\Term;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Illuminate\View\View;

class AttendanceController extends PageController
{
    public function index(): View
    {
        $sessions = Attendance::query()
            ->with(['schoolClass', 'recordedBy'])
            ->latest('date')
            ->paginate(20);

        return $this->page('admin.attendance.index', [
            'crumbTitle' => 'Attendance',
            'crumbSub' => 'Daily tracker',
            'sessions' => $sessions,
        ]);
    }

    public function create(Request $request): View
    {
        $classId = $request->integer('class_id');
        $date = $request->input('date', today()->toDateString());
        $schoolClass = $classId ? SchoolClass::query()->with('students')->find($classId) : null;
        $existing = null;

        if ($schoolClass) {
            $existing = Attendance::query()
                ->with('records')
                ->where('class_id', $schoolClass->id)
                ->whereDate('date', $date)
                ->first();
        }

        return $this->page('admin.attendance.create', [
            'crumbTitle' => 'Attendance',
            'crumbSub' => 'Mark daily attendance',
            'classes' => SchoolClass::query()->orderBy('name')->get(),
            'schoolClass' => $schoolClass,
            'date' => $date,
            'existing' => $existing,
            'statuses' => ['present', 'absent', 'late', 'excused'],
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'class_id' => ['required', 'exists:classes,id'],
            'date' => ['required', 'date'],
            'notes' => ['nullable', 'string'],
            'records' => ['required', 'array', 'min:1'],
            'records.*.student_id' => ['required', 'exists:students,id'],
            'records.*.status' => ['required', Rule::in(['present', 'absent', 'late', 'excused'])],
            'records.*.remarks' => ['nullable', 'string', 'max:255'],
        ]);

        $schoolClass = SchoolClass::query()->findOrFail($validated['class_id']);
        $term = Term::query()->where('is_current', true)->first();

        DB::transaction(function () use ($validated, $schoolClass, $term) {
            $attendance = Attendance::query()->updateOrCreate(
                [
                    'class_id' => $schoolClass->id,
                    'date' => $validated['date'],
                ],
                [
                    'recorded_by' => auth()->user()?->staff_id,
                    'term_id' => $term?->id,
                    'status' => 'closed',
                    'notes' => $validated['notes'] ?? null,
                ],
            );

            foreach ($validated['records'] as $row) {
                AttendanceRecord::query()->updateOrCreate(
                    [
                        'attendance_id' => $attendance->id,
                        'student_id' => $row['student_id'],
                    ],
                    [
                        'status' => $row['status'],
                        'remarks' => $row['remarks'] ?? null,
                    ],
                );
            }
        });

        return $this->redirectWithSuccess('school.attendance.index', 'Attendance saved for '.$schoolClass->name.'.');
    }

    public function termReport(Request $request): View
    {
        $termId = $request->integer('term_id') ?: Term::query()->where('is_current', true)->value('id');
        $classId = $request->integer('class_id') ?: null;

        $terms = Term::query()->with('academicYear')->orderByDesc('starts_on')->get();
        $classes = SchoolClass::query()->orderBy('name')->get();

        $report = collect();

        if ($termId) {
            $query = AttendanceRecord::query()
                ->select([
                    'students.id as student_id',
                    'students.first_name',
                    'students.last_name',
                    'students.admission_number',
                    DB::raw("SUM(CASE WHEN attendance_records.status = 'present' THEN 1 ELSE 0 END) as present_count"),
                    DB::raw("SUM(CASE WHEN attendance_records.status = 'absent' THEN 1 ELSE 0 END) as absent_count"),
                    DB::raw("SUM(CASE WHEN attendance_records.status = 'late' THEN 1 ELSE 0 END) as late_count"),
                    DB::raw("SUM(CASE WHEN attendance_records.status = 'excused' THEN 1 ELSE 0 END) as excused_count"),
                    DB::raw('COUNT(*) as total_sessions'),
                ])
                ->join('attendances', 'attendance_records.attendance_id', '=', 'attendances.id')
                ->join('students', 'attendance_records.student_id', '=', 'students.id')
                ->where('attendances.term_id', $termId)
                ->groupBy('students.id', 'students.first_name', 'students.last_name', 'students.admission_number');

            if ($classId) {
                $query->where('attendances.class_id', $classId);
            }

            $report = $query->orderBy('students.last_name')->get();
        }

        return $this->page('admin.attendance.term-report', [
            'crumbTitle' => 'Attendance',
            'crumbSub' => 'Term report',
            'terms' => $terms,
            'classes' => $classes,
            'termId' => $termId,
            'classId' => $classId,
            'report' => $report,
        ]);
    }
}
