<?php

declare(strict_types=1);

namespace App\Framework\Svg\Elements;

use App\Framework\Svg\ValueObjects\Transform\Transform;

/**
 * Value Object representing SVG g (group) element
 * Groups multiple elements together for transformation and styling
 */
final readonly class GroupElement implements SvgElement
{
    /**
     * @param array<SvgElement> $children
     */
    public function __construct(
        public array $children,
        public ?Transform $transform = null,
        public ?string $id = null,
        public ?string $class = null
    ) {
    }

    public function getElementType(): string
    {
        return 'g';
    }

    public function getAttributes(): array
    {
        $attributes = [];

        if ($this->transform !== null && $this->transform->hasTransformations()) {
            $attributes['transform'] = $this->transform->toSvgValue();
        }

        if ($this->id !== null) {
            $attributes['id'] = $this->id;
        }

        if ($this->class !== null) {
            $attributes['class'] = $this->class;
        }

        return $attributes;
    }

    public function hasTransform(): bool
    {
        return $this->transform !== null && $this->transform->hasTransformations();
    }

    public function getTransform(): ?Transform
    {
        return $this->transform;
    }

    public function toSvg(): string
    {
        $attributes = $this->getAttributes();
        $attributeString = empty($attributes)
            ? ''
            : ' ' . $this->buildAttributeString($attributes);

        $childrenSvg = implode("\n  ", array_map(
            fn (SvgElement $child) => $child->toSvg(),
            $this->children
        ));

        if (empty($childrenSvg)) {
            return "<g{$attributeString} />";
        }

        return "<g{$attributeString}>\n  {$childrenSvg}\n</g>";
    }

    private function buildAttributeString(array $attributes): string
    {
        $parts = [];
        foreach ($attributes as $key => $value) {
            $parts[] = sprintf('%s="%s"', $key, htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8'));
        }

        return implode(' ', $parts);
    }
}
