<?php

declare(strict_types=1);

namespace App\Framework\Svg\ValueObjects\Styling;

/**
 * Value Object representing SVG stroke styling
 */
final readonly class Stroke
{
    public function __construct(
        public SvgColor $color,
        public StrokeWidth $width,
        public Opacity $opacity = new Opacity(1.0),
        public ?StrokeLinecap $linecap = null,
        public ?StrokeLinejoin $linejoin = null,
        public ?string $dasharray = null   // e.g., "5,5" for dashed line
    ) {
    }

    public static function none(): self
    {
        return new self(
            SvgColor::transparent(),
            StrokeWidth::none(),
            new Opacity(0.0)
        );
    }

    public static function solid(SvgColor $color, float $width): self
    {
        return new self($color, new StrokeWidth($width), new Opacity(1.0));
    }

    public static function dashed(SvgColor $color, float $width, string $dasharray): self
    {
        return new self(
            $color,
            new StrokeWidth($width),
            new Opacity(1.0),
            null,
            null,
            $dasharray
        );
    }

    /**
     * Create stroke with rounded ends and joins
     */
    public static function rounded(SvgColor $color, float $width): self
    {
        return new self(
            $color,
            new StrokeWidth($width),
            new Opacity(1.0),
            StrokeLinecap::ROUND,
            StrokeLinejoin::ROUND
        );
    }

    /**
     * Check if stroke is visible
     */
    public function isVisible(): bool
    {
        return $this->opacity->value > 0
            && $this->width->value > 0
            && !$this->color->isTransparent();
    }

    /**
     * Convert to SVG attributes
     */
    public function toSvgAttributes(): array
    {
        $attributes = [
            'stroke' => $this->color->toSvgValue(),
            'stroke-width' => $this->width->toSvgValue(),
        ];

        if ($this->opacity->value < 1.0) {
            $attributes['stroke-opacity'] = $this->opacity->toSvgValue();
        }

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

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

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

        return $attributes;
    }

    public function toArray(): array
    {
        return [
            'color' => $this->color->toSvgValue(),
            'width' => $this->width->value,
            'opacity' => $this->opacity->value,
            'linecap' => $this->linecap?->value,
            'linejoin' => $this->linejoin?->value,
            'dasharray' => $this->dasharray,
            'visible' => $this->isVisible(),
        ];
    }
}
