<?php

declare(strict_types=1);

namespace App\Framework\Svg\Elements;

use App\Framework\Svg\ValueObjects\Geometry\Position;
use App\Framework\Svg\ValueObjects\Text\TextContent;
use App\Framework\Svg\ValueObjects\Text\TextStyle;
use App\Framework\Svg\ValueObjects\Transform\Transform;

/**
 * Value Object representing SVG text element
 */
final readonly class TextElement implements SvgElement
{
    public function __construct(
        public TextContent $content,
        public Position $position,
        public TextStyle $style,
        public ?Transform $transform = null,
        public ?string $id = null,
        public ?string $class = null
    ) {
    }

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

    public function getAttributes(): array
    {
        $attributes = [
            'x' => sprintf('%.2f', $this->position->x),
            'y' => sprintf('%.2f', $this->position->y),
            ...$this->style->toSvgAttributes(),
        ];

        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
    {
        $attributeString = $this->buildAttributeString($this->getAttributes());
        $textContent = $this->content->toSvgSafeString();

        return "<text {$attributeString}>{$textContent}</text>";
    }

    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);
    }
}
