<?php

namespace App\Filament\Resources\ProviderConnectionResource\Pages;

use App\Filament\Concerns\ClearsWorkspaceHubEnvironmentFilterState;
use App\Filament\Resources\ProviderConnectionResource;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Services\Auth\CapabilityResolver;
use App\Support\Auth\Capabilities;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
use Filament\Schemas\Components\EmbeddedTable;
use Filament\Schemas\Components\RenderHook;
use Filament\Schemas\Components\View;
use Filament\Schemas\Schema;
use Filament\View\PanelsRenderHook;

class ListProviderConnections extends ListRecords
{
    use ClearsWorkspaceHubEnvironmentFilterState;

    protected static string $resource = ProviderConnectionResource::class;

    public function mount(): void
    {
        $this->resetWorkspaceHubEnvironmentFilterStateForCleanEntry(request());

        parent::mount();
        $this->resetWorkspaceHubEnvironmentFilterStateForCleanEntry(request());
    }

    private function tableHasRecords(): bool
    {
        return $this->getTableRecords()->count() > 0;
    }

    protected function getHeaderActions(): array
    {
        /** @var CapabilityResolver $resolver */
        $resolver = app(CapabilityResolver::class);

        $actions = [];

        $actions[] = Actions\CreateAction::make()
            ->label('New connection')
            ->url(function (): string {
                $tenant = $this->resolveTenantForCreateAction();

                if (! $tenant instanceof ManagedEnvironment) {
                    return ProviderConnectionResource::getUrl('create');
                }

                return ProviderConnectionResource::getUrl('create', [
                    'environment_id' => (int) $tenant->getKey(),
                ]);
            })
            ->visible(function () use ($resolver): bool {
                if (! $this->tableHasRecords()) {
                    return false;
                }

                $tenant = $this->resolveTenantForCreateAction();
                $user = auth()->user();

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

                if (! $user instanceof User) {
                    return false;
                }

                return $resolver->isMember($user, $tenant);
            })
            ->disabled(function () use ($resolver): bool {
                $tenant = $this->resolveTenantForCreateAction();
                $user = auth()->user();

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

                if (! $user instanceof User) {
                    return true;
                }

                if (! $resolver->isMember($user, $tenant)) {
                    return true;
                }

                return ! $resolver->can($user, $tenant, Capabilities::PROVIDER_MANAGE);
            })
            ->tooltip(function () use ($resolver): ?string {
                $tenant = $this->resolveTenantForCreateAction();

                if (! $tenant instanceof ManagedEnvironment) {
                    return 'Select an environment to create provider connections.';
                }

                $user = auth()->user();

                if (! $user instanceof User) {
                    return null;
                }

                if (! $resolver->isMember($user, $tenant)) {
                    return null;
                }

                if (! $resolver->can($user, $tenant, Capabilities::PROVIDER_MANAGE)) {
                    return 'You do not have permission to create provider connections.';
                }

                return null;
            })
            ->authorize(function () use ($resolver): bool {
                $tenant = $this->resolveTenantForCreateAction();
                $user = auth()->user();

                return $tenant instanceof ManagedEnvironment
                    && $user instanceof User
                    && $resolver->isMember($user, $tenant);
            });

        return $actions;
    }

    public function content(Schema $schema): Schema
    {
        return $schema
            ->components([
                $this->getTabsContentComponent(),
                View::make('filament.partials.workspace-hub-environment-filter-chip')
                    ->viewData(fn (): array => [
                        'label' => $this->environmentFilterChip()['label'] ?? null,
                        'clearUrl' => $this->environmentFilterChip()['clear_url'] ?? null,
                    ])
                    ->visible(fn (): bool => $this->environmentFilterChip() !== null),
                RenderHook::make(PanelsRenderHook::RESOURCE_PAGES_LIST_RECORDS_TABLE_BEFORE),
                EmbeddedTable::make(),
                RenderHook::make(PanelsRenderHook::RESOURCE_PAGES_LIST_RECORDS_TABLE_AFTER),
            ]);
    }

    private function makeEmptyStateCreateAction(): Actions\CreateAction
    {
        /** @var CapabilityResolver $resolver */
        $resolver = app(CapabilityResolver::class);

        return Actions\CreateAction::make()
            ->label('New connection')
            ->url(function (): string {
                $tenant = $this->resolveTenantForCreateAction();

                if (! $tenant instanceof ManagedEnvironment) {
                    return ProviderConnectionResource::getUrl('create');
                }

                return ProviderConnectionResource::getUrl('create', [
                    'environment_id' => (int) $tenant->getKey(),
                ]);
            })
            ->visible(function () use ($resolver): bool {
                $tenant = $this->resolveTenantForCreateAction();
                $user = auth()->user();

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

                if (! $user instanceof User) {
                    return false;
                }

                return $resolver->isMember($user, $tenant);
            })
            ->disabled(function () use ($resolver): bool {
                $tenant = $this->resolveTenantForCreateAction();
                $user = auth()->user();

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

                if (! $user instanceof User) {
                    return true;
                }

                if (! $resolver->isMember($user, $tenant)) {
                    return true;
                }

                return ! $resolver->can($user, $tenant, Capabilities::PROVIDER_MANAGE);
            })
            ->tooltip(function () use ($resolver): ?string {
                $tenant = $this->resolveTenantForCreateAction();

                if (! $tenant instanceof ManagedEnvironment) {
                    return 'Select an environment to create provider connections.';
                }

                $user = auth()->user();

                if (! $user instanceof User) {
                    return null;
                }

                if (! $resolver->isMember($user, $tenant)) {
                    return null;
                }

                if (! $resolver->can($user, $tenant, Capabilities::PROVIDER_MANAGE)) {
                    return 'You do not have permission to create provider connections.';
                }

                return null;
            })
            ->authorize(function () use ($resolver): bool {
                $tenant = $this->resolveTenantForCreateAction();
                $user = auth()->user();

                return $tenant instanceof ManagedEnvironment
                    && $user instanceof User
                    && $resolver->isMember($user, $tenant);
            });
    }

    private function resolveTenantExternalIdForCreateAction(): ?string
    {
        $filterValue = data_get($this->getTableFilterState('tenant'), 'value');

        if (is_string($filterValue) && $filterValue !== '') {
            return $filterValue;
        }

        $requested = ProviderConnectionResource::resolveRequestedTenantExternalId();

        if (is_string($requested) && $requested !== '') {
            return $requested;
        }

        return null;
    }

    /**
     * @return array{label: string, clear_url: string}|null
     */
    private function environmentFilterChip(): ?array
    {
        $environment = ProviderConnectionResource::resolveRequestedEnvironment();

        if (! $environment instanceof ManagedEnvironment) {
            return null;
        }

        return [
            'label' => (string) $environment->name,
            'clear_url' => $this->cleanWorkspaceHubUrl(ProviderConnectionResource::getUrl('index', panel: 'admin')),
        ];
    }

    private function resolveTenantForCreateAction(): ?ManagedEnvironment
    {
        $tenantExternalId = $this->resolveTenantExternalIdForCreateAction();

        if (! is_string($tenantExternalId) || $tenantExternalId === '') {
            return null;
        }

        return ManagedEnvironment::query()
            ->where('slug', $tenantExternalId)
            ->first();
    }

    public function getTableEmptyStateHeading(): ?string
    {
        return 'No provider connections found';
    }

    public function getTableEmptyStateDescription(): ?string
    {
        return 'Start with a platform-managed provider connection. Dedicated overrides are handled separately with stronger authorization.';
    }

    public function getTableEmptyStateActions(): array
    {
        return [$this->makeEmptyStateCreateAction()];
    }
}
