<?php

declare(strict_types=1);

namespace App\Framework\Svg\ValueObjects\Text;

use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\FrameworkException;

/**
 * Value Object representing font weight
 * Supports both numeric (100-900) and named weights
 */
final readonly class FontWeight
{
    public function __construct(
        public int $value
    ) {
        if ($value < 100 || $value > 900 || $value % 100 !== 0) {
            throw FrameworkException::create(
                ErrorCode::VAL_OUT_OF_RANGE,
                'Font weight must be between 100 and 900 in steps of 100'
            )->withData(['value' => $value]);
        }
    }

    /**
     * Named font weights
     */
    public static function thin(): self
    {
        return new self(100);
    }

    public static function extraLight(): self
    {
        return new self(200);
    }

    public static function light(): self
    {
        return new self(300);
    }

    public static function normal(): self
    {
        return new self(400);
    }

    public static function medium(): self
    {
        return new self(500);
    }

    public static function semiBold(): self
    {
        return new self(600);
    }

    public static function bold(): self
    {
        return new self(700);
    }

    public static function extraBold(): self
    {
        return new self(800);
    }

    public static function black(): self
    {
        return new self(900);
    }

    /**
     * Get named weight if applicable
     */
    public function getNamedWeight(): ?string
    {
        return match ($this->value) {
            100 => 'thin',
            200 => 'extra-light',
            300 => 'light',
            400 => 'normal',
            500 => 'medium',
            600 => 'semi-bold',
            700 => 'bold',
            800 => 'extra-bold',
            900 => 'black',
            default => null,
        };
    }

    /**
     * Check if weight is bold or heavier
     */
    public function isBold(): bool
    {
        return $this->value >= 700;
    }

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

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