<?php

declare(strict_types=1);

namespace App\Framework\Svg\Elements;

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

/**
 * Value Object representing SVG line element
 */
final readonly class LineElement implements SvgElement
{
    public function __construct(
        public Position $start,
        public Position $end,
        public Stroke $stroke,
        public ?Transform $transform = null,
        public ?string $id = null,
        public ?string $class = null
    ) {
    }

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

    public function getAttributes(): array
    {
        $attributes = [
            'x1' => sprintf('%.2f', $this->start->x),
            'y1' => sprintf('%.2f', $this->start->y),
            'x2' => sprintf('%.2f', $this->end->x),
            'y2' => sprintf('%.2f', $this->end->y),
            ...$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 "<line {$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);
    }
}
