<?php

namespace App\Core;

class Router
{
    private array $routes = [];
    private string $currentLang = 'fr';

    public function __construct(private Lang $lang)
    {
        $this->currentLang = $lang->getCurrent();
        $this->registerRoutes();
    }

    private function registerRoutes(): void
    {
        $this->add('GET', '/',         'PageController@home');
        $this->add('GET', '/fr',       'PageController@home');
        $this->add('GET', '/en',       'PageController@home');

        $this->add('GET', '/fr/qui-sommes-nous', 'PageController@about');
        $this->add('GET', '/en/about',            'PageController@about');

        $this->add('GET', '/fr/vision', 'PageController@vision');
        $this->add('GET', '/en/vision', 'PageController@vision');

        $this->add('GET', '/fr/activites',          'PageController@activities');
        $this->add('GET', '/en/activities',          'PageController@activities');

        $this->add('GET', '/fr/activites/:pole',    'PageController@pole');
        $this->add('GET', '/en/activities/:pole',   'PageController@pole');

        $this->add('GET', '/fr/activites/:pole/:slug', 'PageController@subsidiary');
        $this->add('GET', '/en/activities/:pole/:slug','PageController@subsidiary');

        $this->add('GET', '/fr/actualites',          'PageController@newsList');
        $this->add('GET', '/en/news',                'PageController@newsList');
        $this->add('GET', '/fr/actualites/:slug',    'PageController@newsDetail');
        $this->add('GET', '/en/news/:slug',          'PageController@newsDetail');

        $this->add('GET',  '/fr/contact', 'PageController@contact');
        $this->add('GET',  '/en/contact', 'PageController@contact');
        $this->add('POST', '/fr/contact', 'PageController@contactSubmit');
        $this->add('POST', '/en/contact', 'PageController@contactSubmit');

        $this->add('GET',  '/admin',          'AdminController@dashboard');
        $this->add('GET',  '/admin/login',    'AdminController@loginForm');
        $this->add('POST', '/admin/login',    'AdminController@loginSubmit');
        
        $this->add('GET',  '/admin/logout',   'AdminController@logout');
        
        $this->add('GET',  '/admin/pages',    'AdminController@pages');
        $this->add('GET',  '/admin/pages/:id/edit', 'AdminController@pageEdit');
        $this->add('POST', '/admin/pages/:id/edit', 'AdminController@pageUpdate');
        
        $this->add('GET',  '/admin/subsidiaries',         'AdminController@subsidiaries');
        $this->add('GET',  '/admin/subsidiaries/:id/edit', 'AdminController@subsidiaryEdit');
        $this->add('POST', '/admin/subsidiaries/:id/edit', 'AdminController@subsidiaryUpdate');
        $this->add('POST', '/admin/subsidiaries/:id/delete', 'AdminController@subsidiaryDelete');
        
        $this->add('GET',  '/admin/news',     'AdminController@news');
        $this->add('GET',  '/admin/news/new', 'AdminController@newsNew');
        $this->add('POST', '/admin/news/new', 'AdminController@newsCreate');
        $this->add('GET',  '/admin/news/:id/edit',   'AdminController@newsEdit');
        $this->add('POST', '/admin/news/:id/edit',   'AdminController@newsUpdate');
        $this->add('POST', '/admin/news/:id/delete', 'AdminController@newsDelete');
        
        $this->add('GET',  '/admin/contacts', 'AdminController@contacts');
        
        $this->add('GET',  '/admin/settings', 'AdminController@settings');
        $this->add('POST', '/admin/settings', 'AdminController@settingsSave');
        
        $this->add('GET',  '/admin/users',           'AdminController@users');
        $this->add('POST', '/admin/users/create',    'AdminController@userCreate');
        $this->add('POST', '/admin/users/toggle/:id', 'AdminController@userToggle');
        $this->add('POST', '/admin/users/delete/:id', 'AdminController@userDelete');
    }

    private function add(string $method, string $uri, string $action): void
    {
        $this->routes[] = [
            'method' => strtoupper($method),
            'uri'    => $uri,
            'action' => $action,
        ];
    }

    public function dispatch(): void
    {
        $requestMethod = $_SERVER['REQUEST_METHOD'] ?? 'GET';
        $requestUri    = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
        $requestUri    = rtrim($requestUri, '/') ?: '/';

        foreach ($this->routes as $route) {
            $params = $this->match($route['uri'], $requestUri);
            if ($params !== false && $route['method'] === $requestMethod) {
                [$controllerName, $method] = explode('@', $route['action']);
                $controllerClass = "App\\Controllers\\{$controllerName}";

                if (!class_exists($controllerClass)) {
                    $this->abort(500, "Controller {$controllerClass} not found");
                    return;
                }

                $controller = new $controllerClass($this->lang);
                if (!method_exists($controller, $method)) {
                    $this->abort(500, "Method {$method} not found");
                    return;
                }

                $controller->$method($params);
                return;
            }
        }

        $this->abort(404, 'Page non trouvée');
    }

    private function match(string $routeUri, string $requestUri): array|false
    {
        $pattern = preg_replace('/\/:([a-z_]+)/', '/(?P<$1>[^/]+)', $routeUri);
        $pattern = '#^' . $pattern . '$#';

        if (preg_match($pattern, $requestUri, $matches)) {
            return array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
        }

        return false;
    }

    private function abort(int $code, string $message): void
    {
        http_response_code($code);
        $title = $code === 404 ? 'Page non trouvée' : 'Erreur serveur';
        include dirname(__DIR__, 2) . "/views/errors/{$code}.php";
        exit;
    }
}
