<?php
namespace App\Controller;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\Response;
use App\Router\Router;
use Shared\Exception\NotFoundHttpException;
use Shared\Exception\NotImplementedException;
use Shared\IArgumentResolver;
use Shared\Log;

class FrontController {
    private Router $router;

    private Container $container;

    public function __construct(Router $router, Container $container) {
        $this->router = $router;
        $this->container = $container;

    }

    public function dispatch(IRequest $request) {
        try {
            $match = $this->router->match($request);
            if (!is_null($match)) {
                $method = $match['target'];
                
                $controller = $this->getController($match['target']);
                $callable = array($controller,$method[1]);    
                $request->addToBody($match['params']);

                if (!is_callable($callable)){
                    throw new NotImplementedException('Controller target is not callable' .'Handle when route target is not a callable :  not handle');
                }
                $argumentResolver = $this->container->get(IArgumentResolver::class);
                $arguments = $argumentResolver->getArguments($request, $callable);

                // check role
                $response = call_user_func_array($callable, $arguments);
                
                // should handle response properly like if it's a HTML, STING, JSON,....
                $response->send();
            } else {
                $this->handleError(404, "Page not found");
            }
        } catch (NotFoundHttpException $e) {
             $this->handleError(404, $e->getMessage());
        }
    }

    private function getController($controllerSpec) {
        if (is_array($controllerSpec)) {
            $controllerName = $controllerSpec[0];
        } else {
            $controllerName = $controllerSpec;
        }
    
        return $this->container->get($controllerName);
    }

    // TODO : Don't work need Antoine help
    private function handleError(int $statusCode, $message) : void {
        if (!$this->container->has(\Twig\Environment::class)) {
            throw new \LogicException('You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".');
        }

        $response = new Response($this->container->get(\Twig\Environment::class)->render('./errorbase.html.twig',['title'=> $message , "nb" => $statusCode, "name" => $message, "descr" => $message ]),$statusCode);
        $response->send();
    }

}

?>
