<?php
    namespace AxiumPHP;

    use AxiumPHP\Core\Router;
    use AxiumPHP\Core\LoggerService;

    class AxiumPHP {
        private array $config;

        public function __construct(array $config = []) {
            $this->config = $config;

            $this->setupErrors();
            $this->setupSession();
            $this->setupTimezone();
            $this->setupConstants();
            $this->setupLogger();
            $this->setupErrorHandlers();

            // Inicia o router
            new Router();
        }

        /**
         * Configura erros
         */
        private function setupErrors(): void {
            $errors = $this->config['errors'];

            if(!empty($errors)) {
                ini_set(option: 'display_errors', value: $errors['display_errors']);
                ini_set(option: 'display_startup_errors', value: $errors['display_startup_errors']);
                ini_set(option: 'log_errors', value: $errors['log_errors']);
                ini_set(option: 'error_log', value: $errors['error_log']);
                error_reporting(error_level: $errors['error_reporting']);
            }
        }

        private function setupConstants() {
            $constants = $this->config['constants'];

            if(!empty($constants)) {
                foreach ($constants as $name => $value) {
                    if (!defined(constant_name: $name)) {
                        define(constant_name: $name, value: $value);
                    }
                }
            }
        }

        /**
         * Configura timezone
         */
        private function setupTimezone(): void {
            $timezone = $this->config['system']['default_timezone'];
            if(!empty($timezone)) {
                date_default_timezone_set(timezoneId: $timezone);
            }
        }

        /**
         * Configura sessão
         */
        private function setupSession(): void {
            $startSession = $this->config['system']['enable_session'];

            if (($startSession === true) && session_status() === PHP_SESSION_NONE) {
                session_start();
            }
        }

        /**
         * Configura logger
         */
        private function setupLogger(): void {
            $logConfig = $this->config['logger'];

            if(!empty($logConfig)) {
                LoggerService::init(
                    driver: $logConfig['driver'],
                    logDir: $logConfig['logDir']
                );
            }
        }

        /**
         * Configura handlers de erro para modo JSON
         */
        private function setupErrorHandlers(): void {
            // Só ativa se modo JSON
            if (defined(constant_name: 'ROUTER_MODE') && ROUTER_MODE === 'JSON') {
                
                // Captura warnings / notices
                set_error_handler(callback: function ($errno, $errstr, $errfile, $errline) {
                    $this->jsonErrorResponse(
                        message: "Erro PHP: {$errstr}", 
                        code: $errno, 
                        extra: [
                            'file' => $errfile,
                            'line' => $errline
                        ]
                    );
                });

                // Captura exceptions não tratadas
                set_exception_handler(callback: function ($exception) {
                    $this->jsonErrorResponse(
                        message: $exception->getMessage(),
                        code: $exception->getCode(),
                        extra: [
                            'file' => $exception->getFile(),
                            'line' => $exception->getLine(),
                            'trace' => $exception->getTrace()
                        ]
                    );
                });

                // Captura fatal errors (shutdown)
                register_shutdown_function(callback: function () {
                    $error = error_get_last();
                    if ($error !== null) {
                        $this->jsonErrorResponse(
                            message: $error['message'],
                            code: $error['type'],
                            extra: [
                                'file' => $error['file'],
                                'line' => $error['line']
                            ]
                        );
                    }
                });
            }
        }

        /**
         * Retorna resposta JSON de erro e encerra execução
         */
        private function jsonErrorResponse(string $message, int $code = 500, array $extra = []): void {
            // Evita headers duplicados
            if (!headers_sent()) {
                http_response_code(response_code: 500);
                header(header: 'Content-Type: application/json; charset=utf-8');
            }

            echo json_encode(
                value: [
                    'status'  => 'error',
                    'message' => $message,
                    'code'    => $code,
                    'extra'   => $extra,
                ], 
                flags: JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
            );

            exit;
        }

        /**
         * Dispara roteador
         */
        public function routerDispatch() {
            if (php_sapi_name() !== 'cli') {
                Router::dispatch();
            }
        }
    }