<?php

namespace App\Filament\SuperAdmin\Pages;

use App\Filament\Clusters\RareAdmin\RareAdminCluster;
use App\Models\GuestPolicySetting;
use App\Services\Audit\SuperAdminAuditLogger;
use Filament\Forms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;

class GuestPolicySettingsPage extends Page
{
    protected static null|string|\BackedEnum $navigationIcon = 'heroicon-o-adjustments-horizontal';

    protected static ?string $cluster = RareAdminCluster::class;

    protected string $view = 'filament.super-admin.pages.guest-policy-settings-page';

    protected static null|string|\UnitEnum $navigationGroup = null;

    protected static ?int $navigationSort = 25;

    public static function getNavigationGroup(): \UnitEnum|string|null
    {
        return __('admin.nav.platform');
    }

    public static function getNavigationLabel(): string
    {
        return __('admin.guest_policy.navigation.label');
    }

    public ?bool $guest_downloads_enabled = true;

    public ?bool $guest_sharing_enabled = true;

    public string $guest_upload_visibility = 'review';

    public int $per_device_upload_limit = 50;

    public int $join_token_failure_limit = 10;

    public int $join_token_failure_decay_minutes = 5;

    public int $join_token_access_limit = 300;

    public int $join_token_access_decay_minutes = 1;

    public int $join_token_download_limit = 120;

    public int $join_token_download_decay_minutes = 1;

    public int $join_token_ttl_hours = 168;

    public int $share_link_ttl_hours = 48;

    public ?int $guest_notification_ttl_hours = null;

    public function mount(): void
    {
        $settings = GuestPolicySetting::current();

        $this->guest_downloads_enabled = (bool) $settings->guest_downloads_enabled;
        $this->guest_sharing_enabled = (bool) $settings->guest_sharing_enabled;
        $this->guest_upload_visibility = $settings->guest_upload_visibility ?? 'review';
        $this->per_device_upload_limit = (int) ($settings->per_device_upload_limit ?? 50);
        $this->join_token_failure_limit = (int) ($settings->join_token_failure_limit ?? 10);
        $this->join_token_failure_decay_minutes = (int) ($settings->join_token_failure_decay_minutes ?? 5);
        $this->join_token_access_limit = (int) ($settings->join_token_access_limit ?? 300);
        $this->join_token_access_decay_minutes = (int) ($settings->join_token_access_decay_minutes ?? 1);
        $this->join_token_download_limit = (int) ($settings->join_token_download_limit ?? 120);
        $this->join_token_download_decay_minutes = (int) ($settings->join_token_download_decay_minutes ?? 1);
        $this->join_token_ttl_hours = (int) ($settings->join_token_ttl_hours ?? 168);
        $this->share_link_ttl_hours = (int) ($settings->share_link_ttl_hours ?? 48);
        $this->guest_notification_ttl_hours = $settings->guest_notification_ttl_hours;
    }

    public function form(Schema $schema): Schema
    {
        return $schema->schema([
            Section::make(__('admin.guest_policy.sections.toggles'))
                ->schema([
                    Forms\Components\Toggle::make('guest_downloads_enabled')
                        ->label(__('admin.guest_policy.fields.guest_downloads_enabled')),
                    Forms\Components\Toggle::make('guest_sharing_enabled')
                        ->label(__('admin.guest_policy.fields.guest_sharing_enabled')),
                    Forms\Components\Select::make('guest_upload_visibility')
                        ->label(__('admin.guest_policy.fields.guest_upload_visibility'))
                        ->options([
                            'review' => __('admin.guest_policy.fields.upload_visibility_review'),
                            'immediate' => __('admin.guest_policy.fields.upload_visibility_immediate'),
                        ])
                        ->required(),
                ])
                ->columns(2),
            Section::make(__('admin.guest_policy.sections.rate_limits'))
                ->schema([
                    Forms\Components\TextInput::make('per_device_upload_limit')
                        ->label(__('admin.guest_policy.fields.per_device_upload_limit'))
                        ->numeric()
                        ->minValue(0)
                        ->helperText(__('admin.guest_policy.help.zero_disables')),
                    Forms\Components\TextInput::make('join_token_failure_limit')
                        ->label(__('admin.guest_policy.fields.join_token_failure_limit'))
                        ->numeric()
                        ->minValue(1),
                    Forms\Components\TextInput::make('join_token_failure_decay_minutes')
                        ->label(__('admin.guest_policy.fields.join_token_failure_decay_minutes'))
                        ->numeric()
                        ->minValue(1),
                    Forms\Components\TextInput::make('join_token_access_limit')
                        ->label(__('admin.guest_policy.fields.join_token_access_limit'))
                        ->numeric()
                        ->minValue(0)
                        ->helperText(__('admin.guest_policy.help.zero_disables')),
                    Forms\Components\TextInput::make('join_token_access_decay_minutes')
                        ->label(__('admin.guest_policy.fields.join_token_access_decay_minutes'))
                        ->numeric()
                        ->minValue(1),
                    Forms\Components\TextInput::make('join_token_download_limit')
                        ->label(__('admin.guest_policy.fields.join_token_download_limit'))
                        ->numeric()
                        ->minValue(0)
                        ->helperText(__('admin.guest_policy.help.zero_disables')),
                    Forms\Components\TextInput::make('join_token_download_decay_minutes')
                        ->label(__('admin.guest_policy.fields.join_token_download_decay_minutes'))
                        ->numeric()
                        ->minValue(1),
                ])
                ->columns(2),
            Section::make(__('admin.guest_policy.sections.retention'))
                ->schema([
                    Forms\Components\TextInput::make('join_token_ttl_hours')
                        ->label(__('admin.guest_policy.fields.join_token_ttl_hours'))
                        ->numeric()
                        ->minValue(0)
                        ->helperText(__('admin.guest_policy.help.join_token_ttl')),
                    Forms\Components\TextInput::make('share_link_ttl_hours')
                        ->label(__('admin.guest_policy.fields.share_link_ttl_hours'))
                        ->numeric()
                        ->minValue(1),
                    Forms\Components\TextInput::make('guest_notification_ttl_hours')
                        ->label(__('admin.guest_policy.fields.guest_notification_ttl_hours'))
                        ->numeric()
                        ->minValue(1)
                        ->nullable()
                        ->helperText(__('admin.guest_policy.help.notification_ttl')),
                ])
                ->columns(2),
        ]);
    }

    public function save(): void
    {
        $this->validate();

        $settings = GuestPolicySetting::query()->firstOrNew(['id' => 1]);
        $settings->guest_downloads_enabled = (bool) $this->guest_downloads_enabled;
        $settings->guest_sharing_enabled = (bool) $this->guest_sharing_enabled;
        $settings->guest_upload_visibility = $this->guest_upload_visibility;
        $settings->per_device_upload_limit = (int) $this->per_device_upload_limit;
        $settings->join_token_failure_limit = (int) $this->join_token_failure_limit;
        $settings->join_token_failure_decay_minutes = (int) $this->join_token_failure_decay_minutes;
        $settings->join_token_access_limit = (int) $this->join_token_access_limit;
        $settings->join_token_access_decay_minutes = (int) $this->join_token_access_decay_minutes;
        $settings->join_token_download_limit = (int) $this->join_token_download_limit;
        $settings->join_token_download_decay_minutes = (int) $this->join_token_download_decay_minutes;
        $settings->join_token_ttl_hours = (int) $this->join_token_ttl_hours;
        $settings->share_link_ttl_hours = (int) $this->share_link_ttl_hours;
        $settings->guest_notification_ttl_hours = $this->guest_notification_ttl_hours;
        $settings->save();

        $changed = $settings->getChanges();

        if ($changed !== []) {
            app(SuperAdminAuditLogger::class)->record(
                'guest_policy.updated',
                $settings,
                SuperAdminAuditLogger::fieldsMetadata(array_keys($changed)),
                source: static::class
            );
        }

        Notification::make()
            ->title(__('admin.guest_policy.notifications.saved'))
            ->success()
            ->send();
    }
}
