<?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 ButtonGroup implements HtmlElement
{
    public HtmlTag $tag;

    public HtmlAttributes $attributes;

    public string $content;

    /**
     * @param array<Button> $buttons
     */
    public function __construct(
        public array $buttons,
        public string $size = 'md',
        public bool $vertical = false,
        public HtmlAttributes $additionalAttributes = new HtmlAttributes()
    ) {
        $this->tag = new HtmlTag(TagName::DIV);

        $classes = ['btn-group', "btn-group--{$this->size}"];
        if ($this->vertical) {
            $classes[] = 'btn-group--vertical';
        }

        $this->attributes = HtmlAttributes::empty()
            ->withClass(implode(' ', $classes))
            ->with('role', 'group');

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

        $buttonsHtml = array_map(
            fn (Button $button) => (string) $button,
            $this->buttons
        );
        $this->content = implode('', $buttonsHtml);
    }

    public static function create(Button ...$buttons): self
    {
        return new self(buttons: $buttons);
    }

    public function withSize(string $size): self
    {
        return new self(
            buttons: $this->buttons,
            size: $size,
            vertical: $this->vertical,
            additionalAttributes: $this->additionalAttributes
        );
    }

    public function asVertical(): self
    {
        return new self(
            buttons: $this->buttons,
            size: $this->size,
            vertical: true,
            additionalAttributes: $this->additionalAttributes
        );
    }

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