<?php
declare(strict_types=1);

/** Workflow tags for tickets (must include meta tag {@see META_ID}). */
final class TicketTagCatalog {
    public const META_ID = 'ticket';

    /** @var array<string, array{label:string,bg:string}> */
    private const STATUS = [
        'open' => ['label' => 'open', 'bg' => '#22c55e'],
        'in-progress' => ['label' => 'in progress', 'bg' => '#3b82f6'],
        'blocked' => ['label' => 'blocked', 'bg' => '#b45309'],
        'wont-fix' => ['label' => "won't fix", 'bg' => '#6b7280'],
        'closed' => ['label' => 'closed', 'bg' => '#6b7280'],
        'rejected' => ['label' => 'rejected', 'bg' => '#b91c1c'],
        'confirmed' => ['label' => 'confirmed', 'bg' => '#047857'],
        'postponed' => ['label' => 'postponed', 'bg' => '#a16207'],
        'urgent' => ['label' => 'urgent', 'bg' => '#dc2626'],
    ];

    /** @return list<string> */
    public static function statusIds(): array {
        return array_keys(self::STATUS);
    }

    /** @return list<array{id:string,label:string,bg:string}> */
    public static function presets(): array {
        $out = [
            ['id' => self::META_ID, 'label' => 'ticket', 'bg' => '#6366f1'],
        ];
        foreach (self::STATUS as $id => $def) {
            $out[] = ['id' => $id, 'label' => $def['label'], 'bg' => $def['bg']];
        }
        return $out;
    }

    /**
     * @param list<mixed> $tags
     * @return list<array{id:string,label:string,bg:string}>
     */
    public static function normalize(array $tags): array {
        $normalized = normalize_report_tags($tags);
        $hasMeta = false;
        $hasStatus = false;
        foreach ($normalized as $t) {
            if ($t['id'] === self::META_ID) {
                $hasMeta = true;
            }
            if (isset(self::STATUS[$t['id']])) {
                $hasStatus = true;
            }
        }
        if (!$hasMeta) {
            $normalized[] = ['id' => self::META_ID, 'label' => 'ticket', 'bg' => '#6366f1'];
        }
        if (!$hasStatus) {
            $normalized[] = ['id' => 'open', 'label' => 'open', 'bg' => '#22c55e'];
        }
        return $normalized;
    }

    public static function validate(array $tags): ?string {
        $normalized = self::normalize($tags);
        $hasMeta = false;
        $hasStatus = false;
        foreach ($normalized as $t) {
            if ($t['id'] === self::META_ID) {
                $hasMeta = true;
            }
            if (isset(self::STATUS[$t['id']])) {
                $hasStatus = true;
            }
        }
        if (!$hasMeta) {
            return 'tags must include ticket meta tag';
        }
        if (!$hasStatus) {
            return 'tags must include a status tag (open, in-progress, closed, …)';
        }
        return null;
    }
}
