<?php

declare(strict_types=1);

namespace App\Filament\Widgets\ManagedEnvironment;

use App\Filament\Resources\ManagedEnvironmentResource\Pages\ViewManagedEnvironment;
use App\Filament\Support\VerificationReportChangeIndicator;
use App\Filament\Support\VerificationReportViewer;
use App\Models\OperationRun;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Services\Tenants\TenantOperabilityService;
use App\Services\Verification\StartVerification;
use App\Support\Auth\Capabilities;
use App\Support\Auth\UiTooltips;
use App\Support\OperationRunLinks;
use App\Support\OperationRunStatus;
use App\Support\OpsUx\OperationUxPresenter;
use App\Support\OpsUx\ProviderOperationStartResultPresenter;
use App\Support\OpsUx\OpsUxBrowserEvents;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Widgets\Widget;

class ManagedEnvironmentVerificationReport extends Widget
{
    protected static bool $isLazy = false;

    protected string $view = 'filament.widgets.managed-environment.managed-environment-verification-report';

    public ?ManagedEnvironment $record = null;

    private function resolveTenant(): ?ManagedEnvironment
    {
        $tenant = Filament::getTenant();

        if ($tenant instanceof ManagedEnvironment) {
            return $tenant;
        }

        return $this->record instanceof ManagedEnvironment ? $this->record : null;
    }

    public function startVerification(StartVerification $verification): void
    {
        $user = auth()->user();

        if (! $user instanceof User) {
            abort(403);
        }

        $tenant = $this->resolveTenant();

        if (! $tenant instanceof ManagedEnvironment) {
            abort(404);
        }

        if (! $user->canAccessTenant($tenant)) {
            abort(404);
        }

        $result = $verification->providerConnectionCheckForTenant(
            tenant: $tenant,
            initiator: $user,
            extraContext: [
                'surface' => [
                    'kind' => 'tenant_verification_widget',
                ],
            ],
        );

        $runUrl = OperationRunLinks::tenantlessView($result->run);
        $notification = app(ProviderOperationStartResultPresenter::class)->notification(
            result: $result,
            blockedTitle: 'Verification blocked',
            runUrl: $runUrl,
        );

        if ($result->status === 'scope_busy') {
            OpsUxBrowserEvents::dispatchRunEnqueued($this);

            $notification->send();

            return;
        }

        if ($result->status === 'deduped') {
            OpsUxBrowserEvents::dispatchRunEnqueued($this);

            $notification->send();

            return;
        }

        if ($result->status === 'blocked') {
            $notification->send();

            return;
        }

        OpsUxBrowserEvents::dispatchRunEnqueued($this);

        $notification->send();
    }

    /**
     * @return array<string, mixed>
     */
    protected function getViewData(): array
    {
        $tenant = $this->resolveTenant();

        if (! $tenant instanceof ManagedEnvironment) {
            return [
                'tenant' => null,
                'run' => null,
                'runData' => null,
                'runUrl' => null,
                'report' => null,
                'isInProgress' => false,
                'canStart' => false,
                'startTooltip' => null,
                'rerunHint' => null,
            ];
        }

        $run = OperationRun::query()
            ->where('managed_environment_id', (int) $tenant->getKey())
            ->where('type', 'provider.connection.check')
            ->orderByDesc('id')
            ->first();

        $report = $run instanceof OperationRun
            ? VerificationReportViewer::report($run)
            : null;
        $changeIndicator = $run instanceof OperationRun
            ? VerificationReportChangeIndicator::forRun($run)
            : null;
        $previousRunUrl = is_array($changeIndicator) && is_numeric($changeIndicator['previous_report_id'] ?? null)
            ? OperationRunLinks::tenantlessView((int) $changeIndicator['previous_report_id'])
            : null;

        $isInProgress = $run instanceof OperationRun
            && (string) $run->status !== OperationRunStatus::Completed->value;

        $user = auth()->user();
        $isTenantMember = $user instanceof User && $user->canAccessTenant($tenant);
        $canOperate = app(TenantOperabilityService::class)->decisionFor($tenant)->canOperate;
        $canStart = $isTenantMember
            && $canOperate
            && $user->can(Capabilities::PROVIDER_RUN, $tenant);

        $lifecycleNotice = $isTenantMember && ! $canOperate
            ? 'Verification can be started from tenant management only while the tenant is active. Consent and connection configuration remain separate from this stored verification report.'
            : null;

        $runData = null;

        if ($run instanceof OperationRun) {
            $context = is_array($run->context ?? null) ? $run->context : [];
            $targetScope = $context['target_scope'] ?? [];
            $targetScope = is_array($targetScope) ? $targetScope : [];

            $runData = [
                'id' => (int) $run->getKey(),
                'type' => (string) $run->type,
                'status' => (string) $run->status,
                'outcome' => (string) $run->outcome,
                'initiator_name' => (string) $run->initiator_name,
                'started_at' => $run->started_at?->toJSON(),
                'completed_at' => $run->completed_at?->toJSON(),
                'target_scope' => $targetScope,
                'failures' => is_array($run->failure_summary ?? null) ? $run->failure_summary : [],
            ];
        }

        return [
            'tenant' => $tenant,
            'run' => $run,
            'runData' => $runData,
            'runUrl' => $run instanceof OperationRun ? OperationRunLinks::tenantlessView($run) : null,
            'report' => $report,
            'surface' => $run instanceof OperationRun
                ? VerificationReportViewer::surface($run, [], [
                    'hostKind' => 'tenant_widget',
                    'changeIndicator' => $changeIndicator,
                    'previousRunUrl' => $previousRunUrl,
                    'hostVariation' => [
                        'ownsNoRunState' => true,
                        'ownsActiveState' => true,
                        'supportsAssist' => false,
                        'supportsAcknowledge' => false,
                        'supportsTechnicalDetailsTrigger' => false,
                    ],
                ])
                : [],
            'redactionNotes' => VerificationReportViewer::redactionNotes($report),
            'isInProgress' => $isInProgress,
            'showStartAction' => ! ($run instanceof OperationRun) && $isTenantMember && $canOperate,
            'canStart' => $canStart,
            'startTooltip' => $isTenantMember && $canOperate && ! $canStart ? UiTooltips::insufficientPermission() : null,
            'lifecycleNotice' => $lifecycleNotice,
            'rerunHint' => $run instanceof OperationRun && $canStart
                ? ViewManagedEnvironment::verificationHeaderActionHint()
                : null,
        ];
    }
}
