<?php

declare(strict_types=1);

namespace App\Framework\View\Components;

use App\Framework\View\ValueObjects\HtmlAttributes;
use App\Framework\View\ValueObjects\HtmlElement;
use App\Framework\View\ValueObjects\HtmlTag;
use App\Framework\View\ValueObjects\StandardHtmlElement;
use App\Framework\View\ValueObjects\TagName;

final readonly class FormRadio implements HtmlElement
{
    public HtmlTag $tag;

    public HtmlAttributes $attributes;

    public string $content;

    public function __construct(
        public string $name,
        public string $value,
        public string $label = '',
        public bool $checked = false,
        public ?string $id = null,
        public bool $required = false,
        public bool $disabled = false,
        public HtmlAttributes $additionalAttributes = new HtmlAttributes()
    ) {
        $this->tag = new HtmlTag(TagName::DIV);
        $this->attributes = HtmlAttributes::empty()->withClass('form-radio-item');
        $this->content = $this->buildContent();
    }

    private function buildContent(): string
    {
        $radioId = $this->id ?? "radio-{$this->name}-{$this->value}";
        $elements = [];

        // Radio input
        $radioAttrs = HtmlAttributes::empty()
            ->withType('radio')
            ->withName($this->name)
            ->withValue($this->value)
            ->withId($radioId)
            ->withClass('form-radio');

        if ($this->checked) {
            $radioAttrs = $radioAttrs->withChecked();
        }
        if ($this->required) {
            $radioAttrs = $radioAttrs->withRequired();
        }
        if ($this->disabled) {
            $radioAttrs = $radioAttrs->withDisabled();
        }

        foreach ($this->additionalAttributes->attributes as $name => $value) {
            $radioAttrs = $radioAttrs->with($name, $value);
        }

        $elements[] = StandardHtmlElement::create(TagName::INPUT, $radioAttrs);

        // Label
        $elements[] = StandardHtmlElement::create(
            TagName::LABEL,
            HtmlAttributes::empty()->withClass('form-radio-label')->with('for', $radioId),
            $this->label
        );

        return implode('', array_map('strval', $elements));
    }

    public static function create(
        string $name,
        string $value,
        string $label
    ): self {
        return new self(name: $name, value: $value, label: $label);
    }

    public function withChecked(bool $checked = true): self
    {
        return new self(
            name: $this->name,
            value: $this->value,
            label: $this->label,
            checked: $checked,
            id: $this->id,
            required: $this->required,
            disabled: $this->disabled,
            additionalAttributes: $this->additionalAttributes
        );
    }

    public function withRequired(bool $required = true): self
    {
        return new self(
            name: $this->name,
            value: $this->value,
            label: $this->label,
            checked: $this->checked,
            id: $this->id,
            required: $required,
            disabled: $this->disabled,
            additionalAttributes: $this->additionalAttributes
        );
    }

    public function __toString(): string
    {
        return (string) StandardHtmlElement::create(
            $this->tag->name,
            $this->attributes,
            $this->content
        );
    }
}
