<?php

declare(strict_types=1);

namespace App\Filament\Resources\BaselineSnapshotResource\Pages;

use App\Filament\Resources\BaselineSnapshotResource;
use App\Models\BaselineSnapshot;
use App\Models\User;
use App\Models\Workspace;
use App\Services\Auth\WorkspaceCapabilityResolver;
use App\Services\Baselines\SnapshotRendering\BaselineSnapshotPresenter;
use App\Support\Auth\Capabilities;
use App\Support\Navigation\CrossResourceNavigationMatrix;
use App\Support\Navigation\RelatedContextEntry;
use App\Support\Navigation\RelatedNavigationResolver;
use Filament\Actions\Action;
use Filament\Infolists\Components\ViewEntry;
use Filament\Resources\Pages\ViewRecord;
use Filament\Schemas\Schema;

class ViewBaselineSnapshot extends ViewRecord
{
    protected static string $resource = BaselineSnapshotResource::class;

    /**
     * @var array<string, mixed>
     */
    public array $enterpriseDetail = [];

    public function mount(int|string $record): void
    {
        parent::mount($record);

        $snapshot = $this->getRecord();

        if ($snapshot instanceof BaselineSnapshot) {
            $snapshot->loadMissing(['baselineProfile', 'items']);

            $relatedContext = app(RelatedNavigationResolver::class)
                ->detailEntries(CrossResourceNavigationMatrix::SOURCE_BASELINE_SNAPSHOT, $snapshot);

            $this->enterpriseDetail = app(BaselineSnapshotPresenter::class)
                ->presentEnterpriseDetail($snapshot, $relatedContext)
                ->toArray();
        }
    }

    protected function authorizeAccess(): void
    {
        $user = auth()->user();
        $snapshot = $this->getRecord();
        $workspace = BaselineSnapshotResource::resolveWorkspace();

        if (! $user instanceof User || ! $snapshot instanceof BaselineSnapshot || ! $workspace instanceof Workspace) {
            abort(404);
        }

        if ((int) $snapshot->workspace_id !== (int) $workspace->getKey()) {
            abort(404);
        }

        /** @var WorkspaceCapabilityResolver $resolver */
        $resolver = app(WorkspaceCapabilityResolver::class);

        if (! $resolver->isMember($user, $workspace)) {
            abort(404);
        }

        if (! $resolver->can($user, $workspace, Capabilities::WORKSPACE_BASELINES_VIEW)) {
            abort(403);
        }
    }

    public function infolist(Schema $schema): Schema
    {
        return $schema
            ->schema([
                ViewEntry::make('enterprise_detail')
                    ->label('')
                    ->view('filament.infolists.entries.enterprise-detail.layout')
                    ->state(fn (): array => $this->enterpriseDetail)
                    ->columnSpanFull(),
            ]);
    }

    protected function getHeaderActions(): array
    {
        return [
            Action::make('primary_related')
                ->label(fn (): string => $this->primaryRelatedEntry()?->actionLabel ?? 'Open related record')
                ->url(fn (): ?string => $this->primaryRelatedEntry()?->targetUrl)
                ->hidden(fn (): bool => ! ($this->primaryRelatedEntry()?->isAvailable() ?? false))
                ->color('gray'),
        ];
    }

    private function primaryRelatedEntry(): ?RelatedContextEntry
    {
        return app(RelatedNavigationResolver::class)
            ->headerEntries(CrossResourceNavigationMatrix::SOURCE_BASELINE_SNAPSHOT, $this->getRecord())[0] ?? null;
    }
}
