<?php

declare(strict_types=1);

namespace App\Framework\Svg\ValueObjects\Transform;

/**
 * Value Object representing SVG transform attribute
 * Supports multiple transformations in sequence
 */
final readonly class Transform
{
    /**
     * @param array<Translation|Rotation|Scale|Skew> $transformations
     */
    public function __construct(
        public array $transformations = []
    ) {
    }

    public static function none(): self
    {
        return new self([]);
    }

    public static function translate(float $x, float $y): self
    {
        return new self([new Translation($x, $y)]);
    }

    public static function rotate(float $degrees, ?float $centerX = null, ?float $centerY = null): self
    {
        return new self([new Rotation($degrees, $centerX, $centerY)]);
    }

    public static function scale(float $x, ?float $y = null): self
    {
        return new self([new Scale($x, $y)]);
    }

    /**
     * Add translation to transform chain
     */
    public function withTranslation(float $x, float $y): self
    {
        return new self([...$this->transformations, new Translation($x, $y)]);
    }

    /**
     * Add rotation to transform chain
     */
    public function withRotation(float $degrees, ?float $centerX = null, ?float $centerY = null): self
    {
        return new self([...$this->transformations, new Rotation($degrees, $centerX, $centerY)]);
    }

    /**
     * Add scale to transform chain
     */
    public function withScale(float $x, ?float $y = null): self
    {
        return new self([...$this->transformations, new Scale($x, $y)]);
    }

    /**
     * Check if transform has any transformations
     */
    public function hasTransformations(): bool
    {
        return count($this->transformations) > 0;
    }

    /**
     * Convert to SVG transform attribute value
     */
    public function toSvgValue(): string
    {
        if (!$this->hasTransformations()) {
            return '';
        }

        return implode(' ', array_map(
            fn ($t) => $t->toSvgString(),
            $this->transformations
        ));
    }

    public function toArray(): array
    {
        return array_map(
            fn ($t) => $t->toArray(),
            $this->transformations
        );
    }

    public function __toString(): string
    {
        return $this->toSvgValue();
    }
}
