<?php

namespace PHPNative\Ui\Widget;

use PHPNative\Framework\TextRenderer;
use PHPNative\Tailwind\Style\Padding;
use PHPNative\Tailwind\Style\Text;
use PHPNative\Ui\Component;

class Label extends Component
{
    private int $intrinsicWidth = 0;
    private int $intrinsicHeight = 0;
    private mixed $textTexture = null;
    private int $textWidth = 0;
    private int $textHeight = 0;

    public function __construct(
        public string $text = '',
        public string $style = '',
    ) {
        parent::__construct($style);
    }

    public function setText(string $text): void
    {
        if ($this->text === $text) {
            return;
        }

        $this->text = $text;
        $this->clearTextTexture();
        $this->markDirty(true);
    }

    public function layout(null|TextRenderer $textRenderer = null): void
    {
        // Call parent to compute styles and setup viewports
        parent::layout($textRenderer);
        // Measure text to get intrinsic size
        if ($textRenderer !== null && $textRenderer->isInitialized()) {
            $textStyle = $this->computedStyles[Text::class] ?? new Text();
            [$this->intrinsicWidth, $this->intrinsicHeight] = $textRenderer->measureText($this->text, $textStyle->size);
            // Adjust viewport to fit text if no explicit size
            if (!isset($this->computedStyles[\PHPNative\Tailwind\Style\Width::class])) {
                $this->viewport->width = $this->intrinsicWidth;
                $this->contentViewport->width = $this->intrinsicWidth;
                if (isset($this->computedStyles[Padding::class]) && ($pd = $this->computedStyles[Padding::class])) {
                    $this->viewport->width = $this->intrinsicWidth + $pd->left + $pd->right;
                    $this->contentViewport->width = $this->intrinsicWidth + $pd->left + $pd->right;
                }
            }

            if (!isset($this->computedStyles[\PHPNative\Tailwind\Style\Height::class])) {
                $this->viewport->height = $this->intrinsicHeight;
                $this->contentViewport->height = $this->intrinsicHeight;

                if (isset($this->computedStyles[Padding::class]) && ($pd = $this->computedStyles[Padding::class])) {
                    $this->viewport->height = $this->intrinsicHeight + $pd->top + $pd->bottom;
                    $this->contentViewport->height = $this->intrinsicHeight + $pd->top + $pd->bottom;
                }
            }
        }
    }

    public function renderContent(&$window, null|TextRenderer $textRenderer = null): void
    {
        if (!$this->visible || $textRenderer === null || !$textRenderer->isInitialized()) {
            return;
        }

        // Get text style from computed styles
        $textStyle = $this->computedStyles[Text::class] ?? new Text();

        // Set text color
        $color = $textStyle->color;
        $red = $color->red >= 0 ? $color->red : 0;
        $green = $color->green >= 0 ? $color->green : 0;
        $blue = $color->blue >= 0 ? $color->blue : 0;
        $alpha = max(0, min(255, $color->alpha));

        $textRenderer->setColor($red / 255, $green / 255, $blue / 255, $alpha / 255);

        if ($this->renderDirty || $this->textTexture === null) {
            $this->clearTextTexture();
            $textureData = $textRenderer->createTextTexture($this->text, $textStyle->size);
            if ($textureData !== null) {
                $this->textTexture = $textureData['texture'];
                $this->textWidth = $textureData['width'];
                $this->textHeight = $textureData['height'];
                if (\function_exists('sdl_set_texture_alpha_mod')) {
                    sdl_set_texture_alpha_mod($this->textTexture, $alpha);
                }
            }
        }

        if ($this->textTexture !== null) {
            sdl_render_texture($window, $this->textTexture, [
                'x' => (int) $this->contentViewport->x,
                'y' => (int) $this->contentViewport->y,
                'w' => $this->textWidth,
                'h' => $this->textHeight,
            ]);
        } else {
            // Fallback: render text directly if texture creation failed
            $textRenderer->drawText(
                $this->text,
                (int) $this->contentViewport->x,
                (int) $this->contentViewport->y,
                $textStyle->size,
            );
        }

        $this->renderDirty = false;
    }

    public function __destruct()
    {
        $this->clearTextTexture();
        parent::__destruct();
    }

    private function clearTextTexture(): void
    {
        if ($this->textTexture !== null) {
            sdl_destroy_texture($this->textTexture);
            $this->textTexture = null;
            $this->textWidth = 0;
            $this->textHeight = 0;
        }
    }
}
