<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Exceptions\SupportCenter\SupportCenterException;
use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Concerns\RegistersDberpNavigationWhenAccessible;
use App\Filament\Pages\Concerns\InteractsWithDberpNavigationGroupBreadcrumbs;
use App\Services\DberpPermissionService;
use App\Services\SupportCenter\HostSystemAuthorizationSyncService;
use App\Support\HostSystemAuthorizationCenterDisplay;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\EmbeddedSchema;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\View as SchemaView;
use Filament\Schemas\Schema;
use Filament\Support\Enums\FontFamily;
use Illuminate\Contracts\Support\Htmlable;
use Throwable;
use UnitEnum;

/**
 * @property-read Schema $content
 * @property-read Schema $infolist
 */
final class HostSystemAuthorizationCenterPage extends Page
{
    use InteractsWithDberpNavigationGroupBreadcrumbs;
    use InteractsWithDberpPermissions;
    use RegistersDberpNavigationWhenAccessible;

    protected static ?string $slug = 'host-system-authorization-center';

    protected static ?int $navigationSort = 82;

    public static function getNavigationGroup(): string|UnitEnum|null
    {
        return __('dberp.nav.system');
    }

    public static function getNavigationLabel(): string
    {
        return __('dberp.labels.host_system_authorization_center');
    }

    public static function getNavigationIcon(): string|BackedEnum|Htmlable|null
    {
        return null;
    }

    public static function canAccess(): bool
    {
        return self::allowsPermission(DberpPermissionService::VIEW_HOST_SYSTEM_LICENSE);
    }

    public static function canSyncAuthorization(): bool
    {
        return self::allowsPermission(DberpPermissionService::SYNC_HOST_SYSTEM_LICENSE);
    }

    public function getTitle(): string|Htmlable
    {
        return __('dberp.system_authorization.page_title');
    }

    public function getSubheading(): string|Htmlable|null
    {
        $display = app(HostSystemAuthorizationCenterDisplay::class);

        if ($display->hasStableAuthorizationSnapshot()) {
            return __('dberp.system_authorization.page_intro_after_stable');
        }

        return __('dberp.system_authorization.page_intro');
    }

    /**
     * @return array<Action>
     */
    protected function getHeaderActions(): array
    {
        return [
            Action::make('syncAuthorization')
                ->label(__('dberp.system_authorization.actions.sync'))
                ->icon('heroicon-o-arrow-path')
                ->color('primary')
                ->action(fn (): mixed => $this->syncAuthorization())
                ->visible(fn (): bool => self::canSyncAuthorization()),
        ];
    }

    public function content(Schema $schema): Schema
    {
        return $schema->components([
            EmbeddedSchema::make('infolist'),
        ]);
    }

    public function defaultInfolist(Schema $schema): Schema
    {
        if (! $schema->hasCustomColumns()) {
            $schema->columns(1);
        }

        return $schema
            ->inlineLabel(false)
            ->record(null);
    }

    public function infolist(Schema $schema): Schema
    {
        $display = app(HostSystemAuthorizationCenterDisplay::class);

        return $schema->components([
            Section::make(__('dberp.system_authorization.sections.binding_hint'))
                ->description(__('dberp.system_authorization.binding_section.description'))
                ->icon('heroicon-o-exclamation-triangle')
                ->iconColor('warning')
                ->schema([
                    TextEntry::make('site_binding_hint')
                        ->label(__('dberp.system_authorization.rows.site_binding_hint'))
                        ->state(__('dberp.system_authorization.hints.complete_site_access_first'))
                        ->color('warning')
                        ->columnSpanFull(),
                ])
                ->visible(fn (): bool => ! $display->isOfficialSiteBound()),
            Section::make(__('dberp.system_authorization.sections.authorization'))
                ->schema([
                    TextEntry::make('authorization_status')
                        ->label(__('dberp.system_authorization.rows.authorization_status'))
                        ->state($display->authorizationLabel())
                        ->badge()
                        ->color(fn (): string => $display->authorizationBadgeColor()),
                    TextEntry::make('official_site_no')
                        ->label(__('dberp.system_authorization.rows.official_site_no'))
                        ->state($display->officialSiteNo())
                        ->copyable()
                        ->fontFamily(FontFamily::Mono)
                        ->visible(fn (): bool => filled($display->officialSiteNo())),
                    TextEntry::make('license_no')
                        ->label(__('dberp.system_authorization.rows.license_no'))
                        ->state($display->licenseNo())
                        ->copyable()
                        ->fontFamily(FontFamily::Mono)
                        ->visible(fn (): bool => filled($display->licenseNo())),
                    TextEntry::make('bound_domains')
                        ->label(__('dberp.system_authorization.rows.bound_domains'))
                        ->listWithLineBreaks()
                        ->bulleted()
                        ->state($display->boundDomainsLines())
                        ->visible(fn (): bool => $display->boundDomainsLines() !== [])
                        ->columnSpanFull(),
                ])
                ->columns(2),
            Section::make(__('dberp.system_authorization.sections.service'))
                ->schema([
                    TextEntry::make('service_status')
                        ->label(__('dberp.system_authorization.rows.service_status'))
                        ->state($display->serviceStatusLabel())
                        ->badge()
                        ->color(fn (): string => $display->serviceStatusBadgeColor()),
                    TextEntry::make('expires_at')
                        ->label(__('dberp.system_authorization.rows.expires_at'))
                        ->state($display->expiresAtLabel())
                        ->visible(fn (): bool => $display->hasServiceExpiry()),
                    TextEntry::make('remaining_service_days')
                        ->label(__('dberp.system_authorization.rows.remaining_service_days'))
                        ->state($display->remainingServiceDaysLabel())
                        ->visible(fn (): bool => $display->hasRemainingServiceDays()),
                ])
                ->columns(2),
            Section::make(__('dberp.system_authorization.sections.entitlements'))
                ->schema([
                    SchemaView::make('components.dberp.authorization.entitlement-summary')
                        ->viewData(fn (): array => [
                            'items' => $display->entitlementSummaryItems(),
                            'emptyMessage' => $display->shouldShowEntitlementsEmptyState()
                                ? (string) __('dberp.system_authorization.entitlements_display.none')
                                : null,
                        ])
                        ->columnSpanFull(),
                ])
                ->visible(fn (): bool => $display->shouldShowEntitlementsSection()),
            Section::make(__('dberp.system_authorization.sections.sync'))
                ->schema([
                    TextEntry::make('last_sync_status')
                        ->label(__('dberp.system_authorization.rows.last_sync_status'))
                        ->state($display->syncStatusLabel())
                        ->badge()
                        ->color(fn (): string => $display->syncStatusBadgeColor()),
                    TextEntry::make('last_synced_at')
                        ->label(__('dberp.system_authorization.rows.last_synced_at'))
                        ->state($display->lastSyncedAtLabel())
                        ->visible(fn (): bool => filled($display->lastSyncedAtLabel())),
                    TextEntry::make('last_sync_hint')
                        ->label(__('dberp.system_authorization.rows.last_sync_message'))
                        ->state($display->lastSyncDisplayHint())
                        ->visible(fn (): bool => filled($display->lastSyncDisplayHint()))
                        ->color('danger')
                        ->columnSpanFull(),
                ])
                ->columns(2)
                ->visible(fn (): bool => $display->shouldShowSyncSection()),
        ]);
    }

    public function syncAuthorization(): void
    {
        if (! self::canSyncAuthorization()) {
            Notification::make()
                ->danger()
                ->title(__('dberp.system_authorization.notifications.sync_denied_title'))
                ->body(__('dberp.system_authorization.notifications.sync_denied_body'))
                ->send();

            return;
        }

        try {
            app(HostSystemAuthorizationSyncService::class)->sync();

            Notification::make()
                ->success()
                ->title(__('dberp.system_authorization.notifications.sync_success_title'))
                ->body(__('dberp.system_authorization.notifications.sync_success_body'))
                ->send();

            $this->redirect(self::getUrl(), navigate: true);

            return;
        } catch (SupportCenterException $exception) {
            Notification::make()
                ->danger()
                ->title(__('dberp.system_authorization.notifications.sync_failed_title'))
                ->body($exception->userFacingMessage())
                ->send();
        } catch (Throwable) {
            Notification::make()
                ->danger()
                ->title(__('dberp.system_authorization.notifications.sync_failed_title'))
                ->body(__('dberp.system_authorization.notifications.sync_failed_body_generic'))
                ->send();
        }
    }
}
