<?php

declare(strict_types=1);

namespace App\Filament\Pages\Monitoring;

use App\Filament\Resources\OperationRunResource;
use App\Filament\Widgets\Operations\OperationsKpiHeader;
use App\Models\OperationRun;
use App\Models\Tenant;
use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\OperateHub\OperateHubShell;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\Workspaces\WorkspaceContext;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use UnitEnum;

class Operations extends Page implements HasForms, HasTable
{
    use InteractsWithForms;
    use InteractsWithTable;

    public string $activeTab = 'all';

    /**
     * @var array<string, mixed>|null
     */
    public ?array $navigationContextPayload = null;

    protected static bool $isDiscovered = false;

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-queue-list';

    protected static string|UnitEnum|null $navigationGroup = 'Monitoring';

    protected static ?string $title = 'Operations';

    // Must be non-static
    protected string $view = 'filament.pages.monitoring.operations';

    public function mount(): void
    {
        $this->navigationContextPayload = is_array(request()->query('nav')) ? request()->query('nav') : null;
        $this->mountInteractsWithTable();
    }

    protected function getHeaderWidgets(): array
    {
        return [
            OperationsKpiHeader::class,
        ];
    }

    /**
     * @return array<Action>
     */
    protected function getHeaderActions(): array
    {
        $operateHubShell = app(OperateHubShell::class);
        $navigationContext = $this->navigationContext();

        $actions = [
            Action::make('operate_hub_scope_operations')
                ->label($operateHubShell->scopeLabel(request()))
                ->color('gray')
                ->disabled(),
        ];

        $activeTenant = $operateHubShell->activeEntitledTenant(request());

        if ($navigationContext?->backLinkLabel !== null && $navigationContext->backLinkUrl !== null) {
            $actions[] = Action::make('operate_hub_back_to_origin_operations')
                ->label($navigationContext->backLinkLabel)
                ->icon('heroicon-o-arrow-left')
                ->color('gray')
                ->url($navigationContext->backLinkUrl);
        } elseif ($activeTenant instanceof Tenant) {
            $actions[] = Action::make('operate_hub_back_to_tenant_operations')
                ->label('Back to '.$activeTenant->name)
                ->icon('heroicon-o-arrow-left')
                ->color('gray')
                ->url(\App\Filament\Pages\TenantDashboard::getUrl(panel: 'tenant', tenant: $activeTenant));
        }

        if ($activeTenant instanceof Tenant) {
            $actions[] = Action::make('operate_hub_show_all_tenants')
                ->label('Show all tenants')
                ->color('gray')
                ->action(function (): void {
                    Filament::setTenant(null, true);

                    app(WorkspaceContext::class)->clearLastTenantId(request());

                    $this->removeTableFilter('tenant_id');

                    $this->redirect('/admin/operations');
                });
        }

        return $actions;
    }

    private function navigationContext(): ?CanonicalNavigationContext
    {
        if (! is_array($this->navigationContextPayload)) {
            return CanonicalNavigationContext::fromRequest(request());
        }

        $request = request()->duplicate(query: ['nav' => $this->navigationContextPayload]);

        return CanonicalNavigationContext::fromRequest($request);
    }

    public function updatedActiveTab(): void
    {
        $this->resetPage();
    }

    public function table(Table $table): Table
    {
        return OperationRunResource::table($table)
            ->query(function (): Builder {
                $workspaceId = app(WorkspaceContext::class)->currentWorkspaceId(request());

                $activeTenant = app(OperateHubShell::class)->activeEntitledTenant(request());

                $query = OperationRun::query()
                    ->with('user')
                    ->latest('id')
                    ->when(
                        $workspaceId,
                        fn (Builder $query): Builder => $query->where('workspace_id', (int) $workspaceId),
                    )
                    ->when(
                        ! $workspaceId,
                        fn (Builder $query): Builder => $query->whereRaw('1 = 0'),
                    )
                    ->when(
                        $activeTenant instanceof Tenant,
                        fn (Builder $query): Builder => $query->where('tenant_id', (int) $activeTenant->getKey()),
                    );

                return $this->applyActiveTab($query);
            });
    }

    private function applyActiveTab(Builder $query): Builder
    {
        return match ($this->activeTab) {
            'active' => $query->whereIn('status', [
                OperationRunStatus::Queued->value,
                OperationRunStatus::Running->value,
            ]),
            'succeeded' => $query
                ->where('status', OperationRunStatus::Completed->value)
                ->where('outcome', OperationRunOutcome::Succeeded->value),
            'partial' => $query
                ->where('status', OperationRunStatus::Completed->value)
                ->where('outcome', OperationRunOutcome::PartiallySucceeded->value),
            'failed' => $query
                ->where('status', OperationRunStatus::Completed->value)
                ->where('outcome', OperationRunOutcome::Failed->value),
            default => $query,
        };
    }
}
