<?php

namespace App\Http\Controllers;

use App\Models\AcademicSession;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class AcademicSessionController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            new Middleware('can:academics.view', only: ['index']),
            new Middleware('can:academics.create', only: ['create', 'store']),
            new Middleware('can:academics.update', only: ['edit', 'update']),
            new Middleware('can:academics.delete', only: ['destroy']),
        ];
    }

    public function index(): View
    {
        $sessions = AcademicSession::withCount('students')->orderByDesc('id')->get();

        return view('academics.sessions.index', compact('sessions'));
    }

    public function create(): View
    {
        return view('academics.sessions.create', ['session' => new AcademicSession()]);
    }

    public function store(Request $request): RedirectResponse
    {
        $data = $this->validateData($request);
        $this->persist(new AcademicSession(), $data);

        return redirect()->route('sessions.index')->with('success', 'Academic session created.');
    }

    public function edit(AcademicSession $session): View
    {
        return view('academics.sessions.edit', compact('session'));
    }

    public function update(Request $request, AcademicSession $session): RedirectResponse
    {
        $data = $this->validateData($request, $session->id);
        $this->persist($session, $data);

        return redirect()->route('sessions.index')->with('success', 'Academic session updated.');
    }

    public function destroy(AcademicSession $session): RedirectResponse
    {
        if ($session->students()->exists()) {
            return back()->with('error', 'Cannot delete a session that has students.');
        }
        $session->delete();

        return redirect()->route('sessions.index')->with('success', 'Academic session deleted.');
    }

    private function validateData(Request $request, ?int $id = null): array
    {
        return $request->validate([
            'name' => ['required', 'string', 'max:50', 'unique:academic_sessions,name'.($id ? ",$id" : '')],
            'start_date' => ['nullable', 'date'],
            'end_date' => ['nullable', 'date', 'after_or_equal:start_date'],
            'is_current' => ['nullable', 'boolean'],
        ]);
    }

    private function persist(AcademicSession $session, array $data): void
    {
        $data['is_current'] = (bool) ($data['is_current'] ?? false);

        DB::transaction(function () use ($session, $data) {
            if ($data['is_current']) {
                AcademicSession::where('id', '!=', $session->id ?? 0)->update(['is_current' => false]);
            }
            $session->fill($data)->save();
        });
    }
}
