<?php

declare(strict_types=1);

namespace App\Framework\Console;

final readonly class ConsoleStyle
{
    public function __construct(
        public ?ConsoleColor $color = null,
        public ?ConsoleFormat $format = null,
        public ?ConsoleColor $background = null,
    ) {
    }

    /**
     * Erstellt einen Style mit den gewünschten Eigenschaften.
     */
    public static function create(
        ?ConsoleColor $color = null,
        ?ConsoleFormat $format = null,
        ?ConsoleColor $backgroundColor = null
    ): self {
        return new self($color, $format, $backgroundColor);
    }

    public function toAnsi(): string
    {
        $codes = [];

        if ($this->format !== null) {
            $codes[] = $this->format->value;
        }

        if ($this->color !== null) {
            $codes[] = $this->color->value;
        }

        if ($this->background !== null) {
            $codes[] = $this->background->value;
        }

        if (empty($codes)) {
            return '';
        }

        return "\033[" . implode(';', $codes) . 'm';
    }

    /**
     * Wendet den Style auf einen Text an.
     */
    public function apply(string $text): string
    {
        $ansi = $this->toAnsi();
        if ($ansi === '') {
            return $text;
        }

        return $ansi . $text . ConsoleColor::RESET->toAnsi();
    }

    // Vordefinierte Styles für häufige Anwendungen
    public static function success(): self
    {
        return new self(ConsoleColor::BRIGHT_GREEN, ConsoleFormat::BOLD);
    }

    public static function error(): self
    {
        return new self(ConsoleColor::BRIGHT_RED, ConsoleFormat::BOLD);
    }

    public static function warning(): self
    {
        return new self(ConsoleColor::BRIGHT_YELLOW, ConsoleFormat::BOLD);
    }

    public static function info(): self
    {
        return new self(ConsoleColor::BRIGHT_BLUE);
    }

    public static function highlight(): self
    {
        return new self(format: ConsoleFormat::BOLD);
    }

    public static function dim(): self
    {
        return new self(format: ConsoleFormat::DIM);
    }
}
