<?php

namespace App\Filament\Support;

use App\Models\Lookups\Status;
use App\Services\CurrentContext;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

/**
 * One context→{name,color} mapping for the DB-backed `statuses` table, reused
 * identically for table badges, filter options, and form/infolist selects
 * (docs/migration-plan.md §5) — no generated PHP enums, since statuses are
 * deliberately per-tenant editable data, not compile-time constants.
 *
 * Cache invalidation: keyed by tenant + context, forgotten automatically by
 * Status's own model events (see App\Models\Lookups\Status::booted()) so no
 * call site can forget to invalidate it.
 */
class StatusLookup
{
    /**
     * @return Collection<string, Status> keyed by status code
     */
    public static function forContext(string $context): Collection
    {
        return Cache::remember(
            static::cacheKey($context),
            now()->addMinutes(10),
            fn () => Status::query()
                ->where('context', $context)
                ->where('is_active', true)
                ->orderBy('sort_order')
                ->get()
                ->keyBy('code'),
        );
    }

    public static function nameOf(string $context, string $code): string
    {
        return static::forContext($context)->get($code)?->name ?? $code;
    }

    public static function colorOf(string $context, string $code): string
    {
        return static::forContext($context)->get($code)?->color ?? 'gray';
    }

    /**
     * Resolve the colour off a status-carrying model instance (GrnStatus,
     * ReturnGrnStatus, or any `statuses`-table Status). The single code path
     * for every status badge: no inline `?->color ?? 'gray'` reads left in
     * resources, and no colour can ever be a name Filament hasn't registered.
     */
    public static function colorOfStatus(?Model $status): string
    {
        if ($status === null) {
            return 'gray';
        }

        $color = trim((string) ($status->color ?? ''));

        return $color !== '' ? $color : 'gray';
    }

    /**
     * @return array<string, string> code => name, for Select/SelectFilter options
     */
    public static function options(string $context): array
    {
        return static::forContext($context)->map(fn (Status $status) => $status->name)->all();
    }

    public static function forgetCache(string $context): void
    {
        Cache::forget(static::cacheKey($context));
    }

    private static function cacheKey(string $context): string
    {
        $tenantId = app(CurrentContext::class)->tenantId() ?? 'central';

        return "status-lookup:{$tenantId}:{$context}";
    }
}
