<?php
declare(strict_types=1);

/**
 * MVC 全局异常基类
 * 后续可派生出 RouteNotFoundException / ParamMissingException 等子类
 */
class MvcException extends \Exception
{
}

/**
 * 全局异常处理器
 */
final class ExceptionHandler
{
    /**
     * 注册为 PHP 全局异常处理器
     */
    public static function register(): void
    {
        set_exception_handler([self::class, 'handle']);
    }

    /**
     * 统一异常处理入口
     * DEBUG 模式下打印异常详情与请求参数，否则记录日志并输出友好提示
     */
    public static function handle(\Throwable $e): void
    {
        if (defined('DEBUG') && DEBUG) {
            $style = 'background:#272822;color:#f8f8f2;padding:10px;margin:5px;border-radius:4px;'
                   . 'text-align:left;white-space:pre-wrap;word-break:break-all;font-size:14px;line-height:1.5;';
            $loc   = '<span style="color:#75715e;">' . htmlspecialchars($e->getFile()) . ':' . $e->getLine() . '</span>';
            echo '<pre style="' . $style . '">' . $loc . "\n"
                . htmlspecialchars($e->getMessage()) . "\n\n"
                . htmlspecialchars($e->getTraceAsString())
                . '</pre>';
            return;
        }

        self::log($e);
        echo '<div style="color:red;padding:20px;text-align:center;border:1px #faa dashed;">系统出现异常错误</div>';
    }

    /**
     * 记录异常日志
     */
    private static function log(\Throwable $e): void
    {
        $message = sprintf(
            "[%s] %s in %s:%d\n%s\n",
            date('Y-m-d H:i:s'),
            $e->getMessage(),
            $e->getFile(),
            $e->getLine(),
            $e->getTraceAsString()
        );
        error_log($message);
    }
}
