<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents\Debug;

use App\Application\LiveComponents\LiveComponentState;
use App\Framework\LiveComponents\Performance\CompiledComponentMetadata;
use App\Framework\LiveComponents\ValueObjects\ComponentId;

/**
 * Debug Panel Renderer
 *
 * Renders development debug panel for LiveComponents.
 *
 * Features:
 * - Component metadata display
 * - State inspection
 * - Render time tracking
 * - Cache hit/miss indicators
 * - Memory usage statistics
 * - Available actions list
 *
 * Note: Only active in development environment
 */
final readonly class DebugPanelRenderer
{
    private const PANEL_TEMPLATE = <<<'HTML'
<div class="livecomponent-debug-panel" data-component-id="%s" style="%s">
    <div class="livecomponent-debug-header" onclick="this.parentElement.classList.toggle('collapsed')">
        <span class="livecomponent-debug-title">🔧 %s</span>
        <span class="livecomponent-debug-toggle">▼</span>
    </div>
    <div class="livecomponent-debug-body">
        <div class="livecomponent-debug-section">
            <strong>Component:</strong> %s
        </div>
        <div class="livecomponent-debug-section">
            <strong>Render Time:</strong> %.2fms
        </div>
        <div class="livecomponent-debug-section">
            <strong>Memory:</strong> %s
        </div>
        <div class="livecomponent-debug-section">
            <strong>Cache:</strong> %s
        </div>
        %s
        %s
        %s
    </div>
</div>
HTML;

    private const PANEL_STYLES = <<<'CSS'
position: relative;
border: 2px solid #ff6b6b;
border-radius: 4px;
margin: 8px 0;
font-family: monospace;
font-size: 12px;
background: #fff;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
CSS;

    /**
     * Render debug panel for component
     *
     * @param ComponentId $componentId Component identifier
     * @param string $componentName Human-readable component name
     * @param string $className Full component class name
     * @param float $renderTimeMs Render time in milliseconds
     * @param LiveComponentState|null $state Component state object
     * @param CompiledComponentMetadata|null $metadata Component metadata
     * @param bool $cacheHit Whether cache was hit
     * @return string Debug panel HTML
     */
    public function render(
        ComponentId $componentId,
        string $componentName,
        string $className,
        float $renderTimeMs,
        ?LiveComponentState $state = null,
        ?CompiledComponentMetadata $metadata = null,
        bool $cacheHit = false
    ): string {
        // Format sections
        $stateSection = $this->renderStateSection($state);
        $actionsSection = $this->renderActionsSection($metadata);
        $metadataSection = $this->renderMetadataSection($metadata);

        return sprintf(
            self::PANEL_TEMPLATE,
            htmlspecialchars($componentId->toString()),
            self::PANEL_STYLES,
            htmlspecialchars($componentName),
            htmlspecialchars($className),
            $renderTimeMs,
            $this->formatMemoryUsage(memory_get_usage()),
            $this->formatCacheStatus($cacheHit),
            $stateSection,
            $actionsSection,
            $metadataSection
        );
    }

    /**
     * Render state section
     */
    private function renderStateSection(?LiveComponentState $state): string
    {
        if ($state === null) {
            return '';
        }

        $stateData = $state->toArray();
        $stateJson = json_encode($stateData, JSON_PRETTY_PRINT);

        return sprintf(
            '<div class="livecomponent-debug-section"><strong>State:</strong><pre style="margin: 4px 0; padding: 8px; background: #f5f5f5; border-radius: 3px; overflow-x: auto;">%s</pre></div>',
            htmlspecialchars($stateJson ?: '{}')
        );
    }

    /**
     * Render actions section
     */
    private function renderActionsSection(?CompiledComponentMetadata $metadata): string
    {
        if ($metadata === null || empty($metadata->actions)) {
            return '';
        }

        $actionsList = array_map(
            fn ($action) => htmlspecialchars($action->name),
            $metadata->actions
        );

        return sprintf(
            '<div class="livecomponent-debug-section"><strong>Actions:</strong> %s</div>',
            implode(', ', $actionsList)
        );
    }

    /**
     * Render metadata section
     */
    private function renderMetadataSection(?CompiledComponentMetadata $metadata): string
    {
        if ($metadata === null) {
            return '';
        }

        $propertyCount = count($metadata->properties);
        $actionCount = count($metadata->actions);

        return sprintf(
            '<div class="livecomponent-debug-section"><strong>Metadata:</strong> %d properties, %d actions</div>',
            $propertyCount,
            $actionCount
        );
    }

    /**
     * Format memory usage
     */
    private function formatMemoryUsage(int $bytes): string
    {
        $units = ['B', 'KB', 'MB', 'GB'];
        $bytes = max($bytes, 0);
        $pow = floor(($bytes > 0 ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);

        $bytes /= (1 << (10 * $pow));

        return round($bytes, 2) . ' ' . $units[$pow];
    }

    /**
     * Format cache status
     */
    private function formatCacheStatus(bool $cacheHit): string
    {
        return $cacheHit
            ? '✅ HIT'
            : '❌ MISS';
    }

    /**
     * Render inline styles for debug panel
     *
     * Should be included once in the page head.
     */
    public function renderStyles(): string
    {
        return <<<'CSS'
<style>
.livecomponent-debug-panel {
    /* Styles already inline for portability */
}
.livecomponent-debug-header {
    background: #ff6b6b;
    color: white;
    padding: 8px 12px;
    cursor: pointer;
    user-select: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: bold;
}
.livecomponent-debug-header:hover {
    background: #ff5252;
}
.livecomponent-debug-body {
    padding: 12px;
    border-top: 1px solid #ff6b6b;
}
.livecomponent-debug-section {
    margin: 6px 0;
    line-height: 1.5;
}
.livecomponent-debug-panel.collapsed .livecomponent-debug-body {
    display: none;
}
.livecomponent-debug-panel.collapsed .livecomponent-debug-toggle {
    transform: rotate(-90deg);
}
.livecomponent-debug-toggle {
    transition: transform 0.2s;
}
</style>
CSS;
    }

    /**
     * Check if debug panel should be rendered
     *
     * Only render in development environment.
     */
    public static function shouldRender(): bool
    {
        return getenv('APP_ENV') === 'development'
            || getenv('LIVECOMPONENT_DEBUG') === 'true';
    }
}
