<?php

namespace App\Http\Controllers;

use App\Http\Requests\AdmissionRequest;
use App\Models\AdmissionApplication;
use App\Models\Branch;
use App\Models\SchoolClass;
use App\Services\AdmissionService;
use App\Support\BranchContext;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\View\View;

class AdmissionController extends Controller implements HasMiddleware
{
    public function __construct(private AdmissionService $service)
    {
    }

    public static function middleware(): array
    {
        return [
            new Middleware('can:viewAny,'.AdmissionApplication::class, only: ['index']),
            new Middleware('can:create,'.AdmissionApplication::class, only: ['create', 'store']),
            new Middleware('permission:admissions.view', only: ['blankForm']),
            new Middleware('can:view,admission', only: ['show']),
            new Middleware('can:update,admission', only: ['edit', 'update', 'approve', 'reject', 'waitlist', 'enroll']),
            new Middleware('can:delete,admission', only: ['destroy']),
        ];
    }

    public function index(): View
    {
        $applications = AdmissionApplication::with('schoolClass')->latest()->get();

        return view('admissions.index', compact('applications'));
    }

    public function create(): View
    {
        return view('admissions.create', ['admission' => new AdmissionApplication(), 'classes' => $this->classes()]);
    }

    public function store(AdmissionRequest $request, BranchContext $context): RedirectResponse
    {
        $data = $request->validated();
        $branchId = $context->currentId() ?? auth()->user()->branch_id ?? \App\Models\Branch::min('id');
        $data['branch_id'] = $branchId;
        $data['application_number'] = AdmissionApplication::nextNumber((int) $branchId);
        $data['status'] = 'pending';

        $application = AdmissionApplication::create($data);

        return redirect()->route('admissions.show', $application)->with('success', 'Admission application created.');
    }

    public function show(AdmissionApplication $admission): View
    {
        $admission->load(['schoolClass', 'family', 'enrolledStudent']);

        return view('admissions.show', ['admission' => $admission]);
    }

    public function edit(AdmissionApplication $admission): View
    {
        return view('admissions.edit', ['admission' => $admission, 'classes' => $this->classes()]);
    }

    public function update(AdmissionRequest $request, AdmissionApplication $admission): RedirectResponse
    {
        $admission->update($request->validated());

        return redirect()->route('admissions.show', $admission)->with('success', 'Application updated.');
    }

    public function destroy(AdmissionApplication $admission): RedirectResponse
    {
        $admission->delete();

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

    public function approve(AdmissionApplication $admission): RedirectResponse
    {
        $this->service->approve($admission);

        return back()->with('success', 'Application approved.');
    }

    public function reject(AdmissionApplication $admission): RedirectResponse
    {
        $this->service->reject($admission);

        return back()->with('success', 'Application rejected.');
    }

    public function waitlist(AdmissionApplication $admission): RedirectResponse
    {
        $this->service->waitlist($admission);

        return back()->with('success', 'Application moved to waiting list.');
    }

    public function enroll(AdmissionApplication $admission): RedirectResponse
    {
        if ($admission->status === 'enrolled') {
            return back()->with('error', 'This application is already enrolled.');
        }

        $student = $this->service->enroll($admission);

        return redirect()->route('students.show', $student)->with('success', 'Student enrolled successfully.');
    }

    /**
     * A blank, print-ready admission form for manual filling.
     * ?format=pdf downloads a PDF, ?format=word downloads a Word (.doc),
     * default renders a print-friendly web page.
     */
    public function blankForm(Request $request, BranchContext $context): Response|View
    {
        $branch = Branch::find($context->currentId()) ?? Branch::query()->orderBy('id')->first();
        $classes = $this->classes();
        $format = $request->query('format', 'web');

        $data = ['branch' => $branch, 'classes' => $classes, 'mode' => $format];

        if ($format === 'pdf') {
            return Pdf::loadView('admissions.blank-form', $data)
                ->setPaper('a4')
                ->download('admission-form.pdf');
        }

        if ($format === 'word') {
            // Word opens an HTML document served with the msword MIME type.
            $html = view('admissions.blank-form', $data)->render();

            return response($html, 200, [
                'Content-Type' => 'application/msword',
                'Content-Disposition' => 'attachment; filename="admission-form.doc"',
            ]);
        }

        return view('admissions.blank-form', $data);
    }

    private function classes()
    {
        return SchoolClass::active()->orderBy('level')->get();
    }
}
