<?php

namespace App\Http\Controllers;

use App\Models\Subject;
use App\Support\BranchContext;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\View\View;

class SubjectController 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
    {
        $subjects = Subject::withCount('classes')->orderBy('name')->get();

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

    public function create(): View
    {
        return view('academics.subjects.create', [
            'subject' => new Subject,
            'classes' => \App\Models\SchoolClass::active()->orderBy('level')->get(),
            'selectedClasses' => [],
        ]);
    }

    public function store(Request $request, BranchContext $context): RedirectResponse
    {
        $data = $this->validateData($request);
        $classIds = $data['class_ids'];
        unset($data['class_ids']);

        $data['branch_id'] = $context->currentId() ?? auth()->user()->branch_id ?? \App\Models\Branch::min('id');
        $subject = Subject::create($data);

        $this->syncClasses($subject, $classIds);

        return redirect()->route('subjects.index')->with('success', 'Subject created and assigned to '.count($classIds).' class(es).');
    }

    public function edit(Subject $subject): View
    {
        return view('academics.subjects.edit', [
            'subject' => $subject,
            'classes' => \App\Models\SchoolClass::active()->orderBy('level')->get(),
            'selectedClasses' => $subject->classes()->pluck('classes.id')->all(),
        ]);
    }

    public function update(Request $request, Subject $subject): RedirectResponse
    {
        $data = $this->validateData($request, $subject);
        $classIds = $data['class_ids'];
        unset($data['class_ids']);

        $subject->update($data);
        $this->syncClasses($subject, $classIds);

        return redirect()->route('subjects.index')->with('success', 'Subject updated.');
    }

    /** Sync the subject to its classes, preserving any existing teacher assignment. */
    private function syncClasses(Subject $subject, array $classIds): void
    {
        $existing = $subject->classes()->get()->mapWithKeys(fn ($c) => [$c->id => $c->pivot->teacher_id]);
        $sync = [];
        foreach ($classIds as $cid) {
            $sync[$cid] = ['branch_id' => $subject->branch_id, 'teacher_id' => $existing[$cid] ?? null];
        }
        $subject->classes()->sync($sync);
    }

    public function destroy(Subject $subject): RedirectResponse
    {
        $subject->delete();

        return redirect()->route('subjects.index')->with('success', 'Subject deleted.');
    }

    private function validateData(Request $request, ?Subject $subject = null): array
    {
        $data = $request->validate([
            'name' => ['required', 'string', 'max:120'],
            'code' => ['nullable', 'string', 'max:30'],
            'is_elective' => ['nullable', 'boolean'],
            'is_active' => ['nullable', 'boolean'],
            'class_ids' => ['required', 'array', 'min:1'],
            'class_ids.*' => ['exists:classes,id'],
        ], [], ['class_ids' => 'classes']);
        $data['is_elective'] = (bool) ($data['is_elective'] ?? false);
        $data['is_active'] = (bool) ($data['is_active'] ?? false);

        return $data;
    }
}
