<?php

namespace App\Filament\Resources\BackupScheduleResource\RelationManagers;

use App\Models\OperationRun;
use App\Models\ManagedEnvironment;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeRenderer;
use App\Support\OperationCatalog;
use App\Support\OperationRunLinks;
use App\Support\Ui\ActionSurface\ActionSurfaceDeclaration;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceInspectAffordance;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceProfile;
use App\Support\Ui\ActionSurface\Enums\ActionSurfaceSlot;
use Closure;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

class BackupScheduleOperationRunsRelationManager extends RelationManager
{
    protected static string $relationship = 'operationRuns';

    protected static ?string $title = 'Executions';

    public static function actionSurfaceDeclaration(): ActionSurfaceDeclaration
    {
        return ActionSurfaceDeclaration::forRelationManager(ActionSurfaceProfile::RelationManager)
            ->exempt(ActionSurfaceSlot::ListHeader, 'Executions relation list has no header actions.')
            ->satisfy(ActionSurfaceSlot::InspectAffordance, ActionSurfaceInspectAffordance::ClickableRow->value)
            ->exempt(ActionSurfaceSlot::ListRowMoreMenu, 'Clickable-row inspection stays primary because this relation manager has no secondary row actions.')
            ->exempt(ActionSurfaceSlot::ListBulkMoreGroup, 'Bulk actions are intentionally omitted for operation run safety.')
            ->exempt(ActionSurfaceSlot::ListEmptyState, 'No empty-state actions are exposed in this embedded relation manager.');
    }

    public function table(Table $table): Table
    {
        return $table
            ->modifyQueryUsing(fn (Builder $query) => $query->where('managed_environment_id', ManagedEnvironment::currentOrFail()->getKey()))
            ->defaultSort('created_at', 'desc')
            ->paginated(\App\Support\Filament\TablePaginationProfiles::relationManager())
            ->recordUrl(function (OperationRun $record): string {
                $record = $this->resolveOwnerScopedOperationRun($record);
                $tenant = ManagedEnvironment::currentOrFail();

                return OperationRunLinks::view($record, $tenant);
            })
            ->columns([
                Tables\Columns\TextColumn::make('created_at')
                    ->label('Enqueued')
                    ->dateTime()
                    ->sortable(),

                Tables\Columns\TextColumn::make('type')
                    ->label('Type')
                    ->formatStateUsing(Closure::fromCallable([self::class, 'formatOperationType'])),

                Tables\Columns\TextColumn::make('status')
                    ->badge()
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::OperationRunStatus))
                    ->color(BadgeRenderer::color(BadgeDomain::OperationRunStatus))
                    ->icon(BadgeRenderer::icon(BadgeDomain::OperationRunStatus))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::OperationRunStatus)),

                Tables\Columns\TextColumn::make('outcome')
                    ->badge()
                    ->formatStateUsing(BadgeRenderer::label(BadgeDomain::OperationRunOutcome))
                    ->color(BadgeRenderer::color(BadgeDomain::OperationRunOutcome))
                    ->icon(BadgeRenderer::icon(BadgeDomain::OperationRunOutcome))
                    ->iconColor(BadgeRenderer::iconColor(BadgeDomain::OperationRunOutcome)),

                Tables\Columns\TextColumn::make('counts')
                    ->label('Counts')
                    ->getStateUsing(function (OperationRun $record): string {
                        $counts = is_array($record->summary_counts) ? $record->summary_counts : [];

                        $total = (int) ($counts['total'] ?? 0);
                        $succeeded = (int) ($counts['succeeded'] ?? 0);
                        $failed = (int) ($counts['failed'] ?? 0);

                        if ($total === 0 && $succeeded === 0 && $failed === 0) {
                            return '—';
                        }

                        return sprintf('%d/%d (%d failed)', $succeeded, $total, $failed);
                    }),
            ])
            ->filters([])
            ->headerActions([])
            ->actions([])
            ->bulkActions([])
            ->emptyStateHeading('No schedule runs yet')
            ->emptyStateDescription('Operation history will appear here after this schedule has been enqueued.');
    }

    private function resolveOwnerScopedOperationRun(mixed $record): OperationRun
    {
        $recordId = $record instanceof OperationRun
            ? (int) $record->getKey()
            : (is_numeric($record) ? (int) $record : 0);

        if ($recordId <= 0) {
            abort(404);
        }

        $resolvedRecord = $this->getOwnerRecord()
            ->operationRuns()
            ->where('managed_environment_id', ManagedEnvironment::currentOrFail()->getKey())
            ->whereKey($recordId)
            ->first();

        if (! $resolvedRecord instanceof OperationRun) {
            abort(404);
        }

        return $resolvedRecord;
    }

    public static function formatOperationType(?string $state): string
    {
        return OperationCatalog::label($state);
    }
}
