<?php

declare(strict_types=1);

namespace App\Framework\Svg\Elements;

use App\Framework\Svg\ValueObjects\Geometry\Position;
use App\Framework\Svg\ValueObjects\Geometry\Radius;
use App\Framework\Svg\ValueObjects\Styling\Fill;
use App\Framework\Svg\ValueObjects\Styling\Stroke;
use App\Framework\Svg\ValueObjects\Transform\Transform;

/**
 * Value Object representing SVG circle element
 */
final readonly class CircleElement implements SvgElement
{
    public function __construct(
        public Position $center,
        public Radius $radius,
        public Fill $fill,
        public ?Stroke $stroke = null,
        public ?Transform $transform = null,
        public ?string $id = null,
        public ?string $class = null
    ) {
    }

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

    public function getAttributes(): array
    {
        $attributes = [
            'cx' => sprintf('%.2f', $this->center->x),
            'cy' => sprintf('%.2f', $this->center->y),
            'r' => $this->radius->toSvgValue(),
            ...$this->fill->toSvgAttributes(),
        ];

        if ($this->stroke !== null && $this->stroke->isVisible()) {
            $attributes = [...$attributes, ...$this->stroke->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());

        return "<circle {$attributeString} />";
    }

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