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

    public HtmlAttributes $attributes;

    public function __construct(
        public string $content,
        public string $size = 'default',
        public bool $fluid = false,
        public HtmlAttributes $additionalAttributes = new HtmlAttributes()
    ) {
        $this->tag = new HtmlTag(TagName::DIV);

        $classes = ['container'];
        if ($this->fluid) {
            $classes[] = 'container--fluid';
        } else {
            $classes[] = "container--{$this->size}";
        }

        $this->attributes = HtmlAttributes::empty()->withClass(implode(' ', $classes));
        foreach ($this->additionalAttributes->attributes as $name => $value) {
            $this->attributes = $this->attributes->with($name, $value);
        }
    }

    public static function create(string $content): self
    {
        return new self(content: $content);
    }

    public static function fluid(string $content): self
    {
        return new self(content: $content, fluid: true);
    }

    public static function small(string $content): self
    {
        return new self(content: $content, size: 'sm');
    }

    public static function large(string $content): self
    {
        return new self(content: $content, size: 'lg');
    }

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

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