<?php

namespace App\Exceptions\Factories;


use App\Exceptions\Auth\ExpiredOtpException;
use App\Exceptions\Auth\IncorrectOtpException;
use App\Exceptions\Handlers\AuthenticationExceptionHandler;
use App\Exceptions\Handlers\BadRequestExceptionHandler;
use App\Exceptions\Handlers\EntityNotFoundExceptionHandler;
use App\Exceptions\Handlers\ExpiredOtpExceptionHandler;
use App\Exceptions\Handlers\IncorrectOtpExceptionHandler;
use App\Exceptions\Handlers\NotFoundExceptionHandler;
use App\Exceptions\Handlers\UnauthorizedExceptionHandler;
use App\Exceptions\Handlers\ValidationExceptionHandler;
use App\Exceptions\LogicalException;
use BadMethodCallException;
use Carbon\Exceptions\InvalidFormatException;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Validation\UnauthorizedException;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ExceptionHandlerFactory
{
    private const EXCEPTION_HANDLERS = [
        LogicalException::class => BadRequestExceptionHandler::class,
        ClientException::class => BadRequestExceptionHandler::class,
        InvalidFormatException::class => BadRequestExceptionHandler::class,
        ModelNotFoundException::class => EntityNotFoundExceptionHandler::class,
        ValidationException::class => ValidationExceptionHandler::class,
        NotFoundHttpException::class => NotFoundExceptionHandler::class,
        MethodNotAllowedHttpException::class => NotFoundExceptionHandler::class,
        BadMethodCallException::class => BadRequestExceptionHandler::class,
        AuthenticationException::class => AuthenticationExceptionHandler::class,
        IncorrectOtpException::class => IncorrectOtpExceptionHandler::class,
        ExpiredOtpException::class => ExpiredOtpExceptionHandler::class,
        UnauthorizedException::class => UnauthorizedExceptionHandler::class,
    ];

    /**
     * @param $exception
     * @return string|null
     */
    public static function getExceptionHandler($exception): ?string
    {
        foreach (self::EXCEPTION_HANDLERS as $exceptionClass => $handler) {
            if ($exception instanceof $exceptionClass) {
                return $handler;
            }
        }
        return null;
    }

    /**
     * @return array
     */
    public static function getHandledExceptionsList(): array
    {
        return array_keys(self::EXCEPTION_HANDLERS);
    }
}
