<?php

declare(strict_types=1);

namespace App\Filament\Widgets\Dashboard;

use App\Filament\Resources\FindingResource;
use App\Models\Finding;
use App\Models\ManagedEnvironment;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
use App\Support\OpsUx\ActiveRuns;
use Filament\Facades\Filament;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;

class RecentDriftFindings extends TableWidget
{
    protected int|string|array $columnSpan = 'full';

    public function table(Table $table): Table
    {
        $tenant = Filament::getTenant();

        return $table
            ->heading('Recent Drift Findings')
            ->query($this->getQuery())
            ->poll(fn (): ?string => ($tenant instanceof ManagedEnvironment) && ActiveRuns::existForTenant($tenant) ? '10s' : null)
            ->defaultSort('created_at', 'desc')
            ->paginated(\App\Support\Filament\TablePaginationProfiles::widget())
            ->columns([
                TextColumn::make('short_id')
                    ->label('ID')
                    ->state(fn (Finding $record): string => '#'.$record->getKey())
                    ->copyable()
                    ->copyableState(fn (Finding $record): string => (string) $record->getKey()),
                TextColumn::make('subject_display_name')
                    ->label('Subject')
                    ->placeholder('—')
                    ->limit(40)
                    ->state(fn (Finding $record): ?string => $record->resolvedSubjectDisplayName())
                    ->description(function (Finding $record): ?string {
                        if (Arr::get($record->evidence_jsonb ?? [], 'summary.kind') !== 'rbac_role_definition') {
                            return null;
                        }

                        return __('findings.drift.rbac_role_definition');
                    })
                    ->tooltip(fn (Finding $record): ?string => $record->resolvedSubjectDisplayName()),
                TextColumn::make('severity')
                    ->badge()
                    ->sortable()
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::FindingSeverity))
                    ->color(BadgeRenderer::color(BadgeDomain::FindingSeverity))
                    ->icon(BadgeRenderer::icon(BadgeDomain::FindingSeverity))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::FindingSeverity)),
                TextColumn::make('status')
                    ->badge()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true)
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::FindingStatus))
                    ->color(BadgeRenderer::color(BadgeDomain::FindingStatus))
                    ->icon(BadgeRenderer::icon(BadgeDomain::FindingStatus))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::FindingStatus)),
                TextColumn::make('created_at')
                    ->label('Created')
                    ->sortable()
                    ->since(),
            ])
            ->recordUrl(fn (Finding $record): ?string => $tenant instanceof ManagedEnvironment
                ? FindingResource::getUrl('view', ['record' => $record], tenant: $tenant)
                : null)
            ->emptyStateHeading('No drift findings')
            ->emptyStateDescription('You\'re looking good — no drift findings to review yet.');
    }

    /**
     * @return Builder<Finding>
     */
    private function getQuery(): Builder
    {
        $tenant = Filament::getTenant();
        $tenantId = $tenant instanceof ManagedEnvironment ? $tenant->getKey() : null;

        return Finding::query()
            ->withSubjectDisplayName()
            ->when($tenantId, fn (Builder $query) => $query->where('managed_environment_id', $tenantId))
            ->where('finding_type', Finding::FINDING_TYPE_DRIFT)
            ->latest('created_at');
    }
}
