<?php

namespace App\Filament\Resources\ProviderConnectionResource\Pages;

use App\Filament\Resources\ProviderConnectionResource;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Auth\CapabilityResolver;
use App\Support\Auth\Capabilities;
use App\Support\Filament\CanonicalAdminTenantFilterState;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

class ListProviderConnections extends ListRecords
{
    protected static string $resource = ProviderConnectionResource::class;

    public function mount(): void
    {
        app(CanonicalAdminTenantFilterState::class)->sync(
            $this->getTableFiltersSessionKey(),
            request: request(),
            tenantFilterName: 'tenant',
            tenantAttribute: 'external_id',
        );

        parent::mount();
    }

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

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

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

                    if (! is_string($tenantExternalId) || $tenantExternalId === '') {
                        return ProviderConnectionResource::getUrl('create');
                    }

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

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

                    if (! $tenant instanceof Tenant) {
                        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 Tenant) {
                        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 Tenant) {
                        return 'Select a tenant 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 Tenant
                        && $user instanceof User
                        && $resolver->isMember($user, $tenant);
                }),
        ];
    }

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

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

                if (! is_string($tenantExternalId) || $tenantExternalId === '') {
                    return ProviderConnectionResource::getUrl('create');
                }

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

                if (! $tenant instanceof Tenant) {
                    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 Tenant) {
                    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 Tenant) {
                    return 'Select a tenant 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 Tenant
                    && $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()
            ?? ProviderConnectionResource::resolveContextTenantExternalId();

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

        return ProviderConnectionResource::resolveContextTenantExternalId();
    }

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

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

        return Tenant::query()
            ->where('external_id', $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()];
    }
}
