<?php

declare(strict_types=1);

namespace App\Filament\Widgets\Inventory;

use App\Filament\Resources\InventorySyncRunResource;
use App\Models\InventoryItem;
use App\Models\InventorySyncRun;
use App\Models\OperationRun;
use App\Models\Tenant;
use App\Services\Inventory\CoverageCapabilitiesResolver;
use App\Support\Inventory\InventoryKpiBadges;
use App\Support\Inventory\InventoryPolicyTypeMeta;
use App\Support\Inventory\InventorySyncStatusBadge;
use Filament\Facades\Filament;
use Filament\Widgets\StatsOverviewWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\HtmlString;

class InventoryKpiHeader extends StatsOverviewWidget
{
    protected static bool $isLazy = false;

    protected int|string|array $columnSpan = 'full';

    /**
     * Inventory KPI aggregation source-of-truth:
     * - `inventory_items.policy_type`
     * - `config('tenantpilot.supported_policy_types')` + `config('tenantpilot.foundation_types')` meta (`restore`, `risk`)
     * - dependency capability via `CoverageCapabilitiesResolver`
     *
     * @return array<Stat>
     */
    protected function getStats(): array
    {
        $tenant = Filament::getTenant();

        if (! $tenant instanceof Tenant) {
            return [
                Stat::make('Total items', 0),
                Stat::make('Coverage', '0%')->description('Restorable 0 • Partial 0'),
                Stat::make('Last inventory sync', '—'),
                Stat::make('Active ops', 0),
                Stat::make('Inventory ops', 0)->description('Dependencies 0 • Risk 0'),
            ];
        }

        $tenantId = (int) $tenant->getKey();

        /** @var array<string, int> $countsByPolicyType */
        $countsByPolicyType = InventoryItem::query()
            ->where('tenant_id', $tenantId)
            ->selectRaw('policy_type, COUNT(*) as aggregate')
            ->groupBy('policy_type')
            ->pluck('aggregate', 'policy_type')
            ->map(fn ($value): int => (int) $value)
            ->all();

        $totalItems = array_sum($countsByPolicyType);

        $restorableItems = 0;
        $partialItems = 0;
        $riskItems = 0;

        foreach ($countsByPolicyType as $policyType => $count) {
            if (InventoryPolicyTypeMeta::isRestorable($policyType)) {
                $restorableItems += $count;
            } elseif (InventoryPolicyTypeMeta::isPartial($policyType)) {
                $partialItems += $count;
            }

            if (InventoryPolicyTypeMeta::isHighRisk($policyType)) {
                $riskItems += $count;
            }
        }

        $coveragePercent = $totalItems > 0
            ? (int) round(($restorableItems / $totalItems) * 100)
            : 0;

        $lastRun = InventorySyncRun::query()
            ->where('tenant_id', $tenantId)
            ->latest('id')
            ->first();

        $lastInventorySyncTimeLabel = '—';
        $lastInventorySyncStatusLabel = '—';
        $lastInventorySyncStatusColor = 'gray';
        $lastInventorySyncStatusIcon = 'heroicon-m-clock';
        $lastInventorySyncViewUrl = null;

        if ($lastRun instanceof InventorySyncRun) {
            $timestamp = $lastRun->finished_at ?? $lastRun->started_at;

            if ($timestamp) {
                $lastInventorySyncTimeLabel = $timestamp->diffForHumans(['short' => true]);
            }

            $status = (string) ($lastRun->status ?? '');

            $badge = InventorySyncStatusBadge::for($status);
            $lastInventorySyncStatusLabel = $badge['label'];
            $lastInventorySyncStatusColor = $badge['color'];
            $lastInventorySyncStatusIcon = $badge['icon'];

            $lastInventorySyncViewUrl = InventorySyncRunResource::getUrl('view', ['record' => $lastRun], tenant: $tenant);
        }

        $badgeColor = $lastInventorySyncStatusColor;

        $lastInventorySyncDescription = Blade::render(<<<'BLADE'
            <div class="flex items-center gap-2">
                <x-filament::badge :color="$badgeColor" size="sm">
                    {{ $statusLabel }}
                </x-filament::badge>

                @if ($viewUrl)
                    <x-filament::link :href="$viewUrl" size="sm">
                        View run
                    </x-filament::link>
                @endif
            </div>
            BLADE, [
            'badgeColor' => $badgeColor,
            'statusLabel' => $lastInventorySyncStatusLabel,
            'viewUrl' => $lastInventorySyncViewUrl,
        ]);

        $activeOps = (int) OperationRun::query()
            ->where('tenant_id', $tenantId)
            ->active()
            ->count();

        $inventoryOps = (int) OperationRun::query()
            ->where('tenant_id', $tenantId)
            ->where('type', 'inventory.sync')
            ->active()
            ->count();

        $resolver = app(CoverageCapabilitiesResolver::class);

        $dependenciesItems = 0;
        foreach ($countsByPolicyType as $policyType => $count) {
            if ($policyType !== '' && $resolver->supportsDependencies($policyType)) {
                $dependenciesItems += $count;
            }
        }

        return [
            Stat::make('Total items', $totalItems),
            Stat::make('Coverage', $coveragePercent.'%')
                ->description(new HtmlString(InventoryKpiBadges::coverage($restorableItems, $partialItems))),
            Stat::make('Last inventory sync', $lastInventorySyncTimeLabel)
                ->description(new HtmlString($lastInventorySyncDescription)),
            Stat::make('Active ops', $activeOps),
            Stat::make('Inventory ops', $inventoryOps)
                ->description(new HtmlString(InventoryKpiBadges::inventoryOps($dependenciesItems, $riskItems))),
        ];
    }
}
