<?php

declare(strict_types=1);

namespace App\Framework\View\Components;

use App\Framework\View\Attributes\ComponentName;
use App\Framework\View\Contracts\StaticComponent;
use App\Framework\View\Dom\ElementNode;
use App\Framework\View\Dom\Node;
use App\Framework\View\Dom\TextNode;

#[ComponentName('button')]
final readonly class Button implements StaticComponent
{
    private string $text;
    private string $type;
    private string $variant;
    private string $size;
    private ?string $href;
    private bool $disabled;
    private bool $fullWidth;
    private ?string $icon;

    public function __construct(
        string $content = '',
        array $attributes = []
    ) {
        // Content is the button text
        $this->text = $content;

        // Extract attributes with defaults
        $this->type = $attributes['type'] ?? 'button';
        $this->variant = $attributes['variant'] ?? 'primary';
        $this->size = $attributes['size'] ?? 'md';
        $this->href = $attributes['href'] ?? null;
        $this->disabled = isset($attributes['disabled'])
            ? filter_var($attributes['disabled'], FILTER_VALIDATE_BOOLEAN)
            : false;
        $this->fullWidth = isset($attributes['full-width'])
            ? filter_var($attributes['full-width'], FILTER_VALIDATE_BOOLEAN)
            : false;
        $this->icon = $attributes['icon'] ?? null;
    }

    public function getRootNode(): Node
    {
        // Determine element based on href
        $element = $this->href !== null
            ? new ElementNode('a')
            : new ElementNode('button');

        // Build CSS classes
        $classes = ['btn', "btn--{$this->variant}", "btn--{$this->size}"];
        if ($this->fullWidth) {
            $classes[] = 'btn--full-width';
        }
        if ($this->disabled && $this->href !== null) {
            $classes[] = 'btn--disabled';
        }

        $element->setAttribute('class', implode(' ', $classes));

        // Set element-specific attributes
        if ($this->href !== null) {
            $element->setAttribute('href', $this->href);
            if ($this->disabled) {
                $element->setAttribute('aria-disabled', 'true');
            }
        } else {
            $element->setAttribute('type', $this->type);
            if ($this->disabled) {
                $element->setAttribute('disabled', 'disabled');
            }
        }

        // Build content
        $contentHtml = $this->icon !== null
            ? "<span class=\"btn__icon\">{$this->icon}</span><span class=\"btn__text\">" . htmlspecialchars($this->text) . "</span>"
            : htmlspecialchars($this->text);

        $element->appendChild(new TextNode($contentHtml));

        return $element;
    }

    // Factory methods for programmatic usage
    public static function primary(string $text): self
    {
        return new self($text, ['variant' => 'primary']);
    }

    public static function secondary(string $text): self
    {
        return new self($text, ['variant' => 'secondary']);
    }

    public static function danger(string $text): self
    {
        return new self($text, ['variant' => 'danger']);
    }

    public static function success(string $text): self
    {
        return new self($text, ['variant' => 'success']);
    }

    public static function ghost(string $text): self
    {
        return new self($text, ['variant' => 'ghost']);
    }

    public static function link(string $text, string $href): self
    {
        return new self($text, ['href' => $href]);
    }
}
