<?php

namespace App\Filament\Resources\Concerns;

use App\Filament\Support\StatusLookup;
use App\Models\Lookups\Status;
use Filament\Schemas\Components\Tabs\Tab;

/**
 * One-line opt-in status tabs for a list page, generated from a
 * Status::CTX_* context: a leading "All" tab plus one tab per active status
 * in sort_order, each carrying a live count badge in the status's own colour
 * and filtering the table by `status_id`.
 *
 *   use HasStatusTabs;
 *   protected static string $tabStatusContext = Status::CTX_SALES_ORDER;
 *
 * Resources whose status lives on a differently-named column (e.g. Invoice's
 * payment_status_id) additionally override tabStatusColumn() (default
 * status_id).
 *
 * Counts are computed with ONE grouped query across all tabs, never one query
 * per tab. All badge closures defer until render, so a data change is
 * reflected on the next page load without extra wiring.
 */
trait HasStatusTabs
{
    protected static function tabStatusColumn(): string
    {
        return 'status_id';
    }

    /**
     * @return array<string, Tab>
     */
    public function getTabs(): array
    {
        $context = static::$tabStatusContext;
        $statuses = StatusLookup::forContext($context);
        $column = static::tabStatusColumn();

        $counts = null;
        $countFor = function (string $key) use (&$counts, $column): int {
            if ($counts === null) {
                $counts = static::getResource()::getEloquentQuery()
                    ->selectRaw($column.' as status_key, COUNT(*) as status_count')
                    ->groupBy($column)
                    ->get()
                    ->pluck('status_count', 'status_key')
                    ->map(fn ($count): int => (int) $count)
                    ->all();
            }

            return $key === 'all'
                ? array_sum($counts)
                : (int) ($counts[$key] ?? 0);
        };

        $tabs = [
            'all' => Tab::make('All')->badge(fn (): int => $countFor('all')),
        ];

        foreach ($statuses as $status) {
            $tabs[$status->code] = Tab::make($status->name)
                ->badge(fn () => $countFor((string) $status->id))
                ->badgeColor(StatusLookup::colorOf($context, $status->code))
                ->modifyQueryUsing(
                    fn ($query) => $query->where($column, $status->id),
                );
        }

        return $tabs;
    }
}
