<?php
declare(strict_types=1);

namespace App\Framework\ErrorHandling\View;

use App\Framework\ErrorHandling\ErrorContext;
use App\Framework\Meta\MetaData;
use App\Framework\Meta\OpenGraphTypeWebsite;
use App\Framework\SyntaxHighlighter\FileHighlighter;
use App\Framework\View\RenderContext;
use App\Framework\View\TemplateRenderer;
use Throwable;

/**
 * Renderer für Fehlerseiten unter Verwendung des View-Systems
 */
final readonly class ErrorTemplateRenderer implements ErrorViewRendererInterface
{
    public function __construct(
        private TemplateRenderer $renderer,
        private string $debugTemplate = 'debug',
        private string $productionTemplate = 'production'
    ) {}

    /**
     * Rendert eine Fehlerseite basierend auf dem ErrorContext
     */
    public function render(ErrorContext $context, bool $isDebug = false): string
    {
        $template = $isDebug ? $this->debugTemplate : $this->productionTemplate;

        try {
            // Sichere Datenaufbereitung ohne Closures oder komplexe Objekte
            $safeData = [
                'code' => new FileHighlighter()($context->exception->getFile(), $context->exception->getLine() -10, 10),
                'errorClass' => $context->exception::class,
                'errorMessage' => $context->exception->getMessage(),
                'error' => [
                    'message' => $context->exception->getMessage(),
                    'file' => $context->exception->getFile(),
                    'line' => $context->exception->getLine(),
                    'trace' => $context->exception->getTraceAsString(),
                    'class' => get_class($context->exception),
                ],
                'requestId' => $context->requestId->toString(),
                'timestamp' => $context->additionalData['timestamp'] ?? date('c'),
                'level' => $context->level->name,
                'memory' => $context->additionalData['memory_usage'] ?? 0
            ];

            $renderContext = new RenderContext(
                template: $template,
                metaData: new MetaData('', '', new OpenGraphTypeWebsite),
                data: $safeData
            );

            $renderedContent = $this->renderer->render($renderContext);

            if($renderedContent === ""){
                throw new \Exception("Template Renderer returned empty string");
            }

            return $renderedContent;
        } catch (Throwable $e) {
            // Fallback falls das Template-Rendering fehlschlägt
            return $this->createFallbackErrorPage($context, $isDebug, $e);
        }
    }

    /**
     * Erstellt eine einfache Fehlerseite als Fallback
     */
    private function createFallbackErrorPage(ErrorContext $context, bool $isDebug, ?Throwable $renderException = null): string
    {
        $exception = $context->exception;

        if ($isDebug) {
            $content = sprintf(
                '<!DOCTYPE html>
                <html>
                <head>
                    <meta charset="UTF-8">
                    <title>Anwendungsfehler</title>
                    <style>
                        body { font-family: sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
                        .error-container { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 20px; margin: 20px 0; }
                        .error-title { color: #dc3545; margin-top: 0; }
                        .error-meta { background: #e9ecef; padding: 10px; border-radius: 4px; font-size: 0.9em; margin: 10px 0; }
                        .error-trace { background: #f1f3f5; padding: 15px; border-radius: 4px; overflow-x: auto; font-family: monospace; font-size: 0.9em; }
                        .error-info { margin-bottom: 20px; }
                        .request-id { font-family: monospace; color: #6c757d; }
                        .render-error { margin-top: 30px; padding-top: 20px; border-top: 1px dashed #dee2e6; }
                    </style>
                </head>
                <body>
                    <div class="error-container">
                        <h1 class="error-title">Anwendungsfehler: %s</h1>

                        <div class="error-meta">
                            <strong>Request-ID:</strong> <span class="request-id">%s</span><br>
                            <strong>Zeit:</strong> %s<br>
                            <strong>Fehler-Level:</strong> %s
                        </div>

                        <div class="error-info">
                            <p><strong>Datei:</strong> %s</p>
                            <p><strong>Zeile:</strong> %d</p>
                        </div>

                        <h3>Stack Trace:</h3>
                        <div class="error-trace">%s</div>

                        %s
                    </div>
                </body>
                </html>',
                htmlspecialchars($exception->getMessage()),
                htmlspecialchars($context->requestId->toString()),
                htmlspecialchars($context->additionalData['timestamp'] ?? date('c')),
                htmlspecialchars($context->level->name),
                htmlspecialchars($exception->getFile()),
                $exception->getLine(),
                nl2br(htmlspecialchars($exception->getTraceAsString())),
                $renderException ? '<div class="render-error"><h3>Fehler beim Rendern der Fehlerseite:</h3><p>' .
                htmlspecialchars($renderException->getMessage()) . '</p></div>' : ''
            );
        } else {
            // Produktions-Fallback mit minimalen Informationen
            $content = sprintf(
                '<!DOCTYPE html>
                <html lang="de">
                <head>
                    <meta charset="UTF-8">
                    <title>Fehler</title>
                    <style>
                        body { font-family: sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 40px 20px; text-align: center; }
                        .error-container { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 40px 20px; }
                        .error-title { color: #dc3545; margin-top: 0; }
                        .request-id { font-family: monospace; color: #6c757d; font-size: 0.8em; margin-top: 30px; }
                    </style>
                </head>
                <body>
                    <div class="error-container">
                        <h1 class="error-title">Es ist ein Fehler aufgetreten</h1>
                        <p>Bitte versuchen Sie es später erneut oder kontaktieren Sie den Support.</p>
                        <p class="request-id">Request-ID: %s</p>
                    </div>
                </body>
                </html>',
                htmlspecialchars($context->requestId->toString())
            );
        }

        return $content;
    }
}
