<?php

namespace App\Filters;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use App\Exceptions\SchoolYear\InvalidSchoolYearSelectionException;
use App\Exceptions\SchoolYear\SchoolYearConfigurationException;
use App\Exceptions\SchoolYear\SchoolYearNotFoundException;
use Throwable;

final class RequireSchoolYearFilter implements FilterInterface
{
    public function before(RequestInterface $request, $arguments = null)
    {
        if (! $request instanceof IncomingRequest) {
            return null;
        }

        try {
            service('schoolYearContext')->resolve($request);
            return null;
        } catch (Throwable $e) {
            log_message('warning', 'School-year request rejected: {message}', [
                'message' => $e->getMessage(),
            ]);

            $status = $this->statusCodeFor($e);

            if ($request->isAJAX() || str_contains(strtolower($request->getHeaderLine('Accept')), 'application/json')) {
                return service('response')
                    ->setStatusCode($status)
                    ->setJSON([
                        'status' => $status,
                        'error' => 'Invalid school year',
                        'message' => $e->getMessage(),
                    ]);
            }

            return service('response')
                ->setStatusCode($status)
                ->setBody(view('errors/school_year', [
                    'message' => $status >= 500
                        ? 'School-year configuration is invalid. Please contact an administrator.'
                        : $e->getMessage(),
                ]));
        }
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        return null;
    }

    private function statusCodeFor(Throwable $e): int
    {
        if ($e instanceof InvalidSchoolYearSelectionException) {
            return 400;
        }

        if ($e instanceof SchoolYearNotFoundException) {
            return 404;
        }

        if ($e instanceof SchoolYearConfigurationException) {
            return 500;
        }

        return 400;
    }
}
