<?php

declare(strict_types=1);

final class SpeciesService
{
    private static ?array $labels = null;
    public const CATEGORIES = [
        'animaux_compagnie' => 'Animaux de compagnie',
        'nac' => 'NAC',
        'animal_ferme' => 'Animaux de ferme',
        'faune_sauvage' => 'Faune sauvage',
        'autre' => 'Autre',
    ];
    public static function categoryLabel(string $key): string
    {
        return t('species.category.' . $key, [], self::CATEGORIES[$key] ?? $key);
    }

    public static function all(bool $activeOnly = false): array
    {
        $sql =
            'SELECT s.*,(SELECT COUNT(*) FROM animals a WHERE lower(trim(a.species))=lower(s.code)) animal_count FROM ref_species s';
        if ($activeOnly) {
            $sql .= ' WHERE s.active=1';
        }
        $sql .= ' ORDER BY s.sort_order,s.name COLLATE NOCASE';
        return DB::pdo()->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function activeWithCurrent(?string $current): array
    {
        $rows = self::all(true);
        $current = self::normalize((string) $current);
        if ($current !== '' && !array_filter($rows, static fn(array $r): bool => $r['code'] === $current)) {
            $stmt = DB::pdo()->prepare('SELECT * FROM ref_species WHERE code=:code');
            $stmt->execute([':code' => $current]);
            if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                $rows[] = $row;
            }
        }
        return $rows;
    }

    public static function normalize(string $value): string
    {
        $value = mb_strtolower(trim($value));
        return match ($value) {
            'cat' => 'chat',
            'dog' => 'chien',
            default => $value,
        };
    }

    public static function exists(string $code, bool $activeOnly = true): bool
    {
        $sql = 'SELECT 1 FROM ref_species WHERE code=:code' . ($activeOnly ? ' AND active=1' : '');
        $stmt = DB::pdo()->prepare($sql);
        $stmt->execute([':code' => self::normalize($code)]);
        return (bool) $stmt->fetchColumn();
    }

    public static function isCat(?string $code): bool
    {
        return self::normalize((string) $code) === 'chat';
    }

    public static function label(?string $code): string
    {
        $code = self::normalize((string) $code);
        if (self::$labels === null) {
            self::$labels = [];
            foreach (self::all(false) as $row) {
                self::$labels[$row['code']] = $row['name'];
            }
        }
        return self::$labels[$code] ?? ($code !== '' ? ucfirst(str_replace('-', ' ', $code)) : 'Espèce inconnue');
    }
}
