<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Helpers\LicenseManager;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Actions;
use Filament\Schemas\Components\Form;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Illuminate\Support\Facades\Storage;

/**
 * @property-read Schema $form
 */
class Registration extends Page
{
    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedKey;

    protected static ?string $navigationLabel = 'Registration';

    protected static ?int $navigationSort = 520;

    protected string $view = 'filament.pages.registration';

    public static function isDiscovered(): bool
    {
        return false;
    }

    /** @var array<string, mixed>|null */
    public ?array $data = [];

    public string $currentKey = '';

    public bool $isLicensed = false;

    public bool $isLegacyKey = false;

    /** @var array<string, mixed>|null */
    public ?array $licensePayload = null;

    public function mount(): void
    {
        $this->refreshLicenseState();
        $this->form->fill();
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Form::make([
                    Section::make(fn () => $this->isLicensed ? 'Replace License' : 'Activate License')
                        ->description(fn () => $this->isLicensed
                            ? 'Upload or paste a valid license key to replace the current one.'
                            : 'Upload or paste the license key you received by email.')
                        ->schema([
                            Tabs::make('Activation Method')
                                ->tabs([
                                    Tabs\Tab::make('Paste Key')
                                        ->icon(Heroicon::OutlinedClipboard)
                                        ->schema([
                                            Textarea::make('pasted_key')
                                                ->label('License Key')
                                                ->placeholder('Paste your AMX-v3-... license key here')
                                                ->rows(4)
                                                ->extraAttributes(['class' => 'font-mono text-xs'])
                                                ->helperText('Copy the full key from the email you received and paste it here.'),
                                        ]),
                                    Tabs\Tab::make('Upload File')
                                        ->icon(Heroicon::OutlinedArrowUpTray)
                                        ->schema([
                                            FileUpload::make('key_file')
                                                ->label('License Key File')
                                                ->disk('local')
                                                ->directory('license-uploads')
                                                ->acceptedFileTypes(['text/plain', 'application/octet-stream'])
                                                ->maxSize(64)
                                                ->helperText('Upload the license.key file attached to your registration email.'),
                                        ]),
                                ]),
                        ]),
                ])
                    ->livewireSubmitHandler('activate')
                    ->footer([
                        Actions::make([
                            Action::make('activate')
                                ->label(fn () => $this->isLicensed ? 'Replace License' : 'Activate License')
                                ->icon(fn () => $this->isLicensed ? Heroicon::OutlinedArrowPath : Heroicon::OutlinedKey)
                                ->color(fn () => $this->isLicensed ? 'warning' : 'primary')
                                ->submit('activate'),
                        ]),
                    ]),
            ])
            ->statePath('data');
    }

    public function activate(): void
    {
        $data = $this->form->getState();

        $keyText = $this->resolveKeyFromFormData($data);

        if ($keyText === null || trim($keyText) === '') {
            Notification::make()
                ->title('No license key provided')
                ->body('Please paste your license key or upload a license.key file.')
                ->warning()
                ->send();

            return;
        }

        $keyText = trim($keyText);

        if (! LicenseManager::isValidStructure($keyText)) {
            Notification::make()
                ->title('Invalid license key format')
                ->body('The key does not appear to be a valid AMX license key. Please check that you copied the full key.')
                ->danger()
                ->send();

            return;
        }

        if (! LicenseManager::verify($keyText)) {
            Notification::make()
                ->title('License key verification failed')
                ->body('The signature on this license key is not valid. Please contact support if you believe this is an error.')
                ->danger()
                ->send();

            return;
        }

        $payload = LicenseManager::decode($keyText);

        if ($payload !== null && LicenseManager::isExpired($payload)) {
            Notification::make()
                ->title('License key has expired')
                ->body('This license key expired on '.date('F j, Y', strtotime($payload['expires'])).'. Please contact support to renew your license.')
                ->danger()
                ->send();

            return;
        }

        LicenseManager::store($keyText);

        $this->cleanUpUploadedFile($data);

        $this->refreshLicenseState();

        $this->form->fill();

        $name = $this->licensePayload['name'] ?? 'Unknown';

        Notification::make()
            ->title('License activated successfully')
            ->body("Welcome, {$name}! Your installation is now registered.")
            ->success()
            ->send();

        if ($this->licensePayload !== null && LicenseManager::isExpiringSoon($this->licensePayload)) {
            $expiry = $this->licensePayload['expires'];

            Notification::make()
                ->title('License expiring soon')
                ->body('This license key expires on '.date('F j, Y', strtotime($expiry)).'. Please contact support to renew before it expires.')
                ->warning()
                ->persistent()
                ->send();
        }
    }

    private function refreshLicenseState(): void
    {
        $this->currentKey = LicenseManager::read() ?? '';
        $this->isLicensed = $this->currentKey !== '' && LicenseManager::verify($this->currentKey);
        $this->licensePayload = $this->isLicensed ? LicenseManager::decode($this->currentKey) : null;
        $this->isLegacyKey = $this->isLicensed && $this->licensePayload === null;
    }

    /**
     * @param  array<string, mixed>  $data
     */
    private function resolveKeyFromFormData(array $data): ?string
    {
        if (! empty($data['pasted_key'])) {
            return $data['pasted_key'];
        }

        if (! empty($data['key_file'])) {
            $filePath = $data['key_file'];
            if (Storage::disk('local')->exists($filePath)) {
                return Storage::disk('local')->get($filePath);
            }
        }

        return null;
    }

    /**
     * @param  array<string, mixed>  $data
     */
    private function cleanUpUploadedFile(array $data): void
    {
        if (! empty($data['key_file'])) {
            Storage::disk('local')->delete($data['key_file']);
        }
    }
}
