<?php

namespace App\Filament\Admin\Resources\Users\Schemas;

use App\Models\DnsSetting;
use Filament\Actions\Action;
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\Group;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;

class UserForm
{
    /**
     * Generate a secure password with uppercase, lowercase, numbers, and special characters
     */
    public static function generateSecurePassword(int $length = 16): string
    {
        $uppercase = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
        $lowercase = 'abcdefghjkmnpqrstuvwxyz';
        $numbers = '23456789';
        $special = '!@#$%^&*';

        // Ensure at least one of each type
        $password = $uppercase[random_int(0, strlen($uppercase) - 1)]
            . $lowercase[random_int(0, strlen($lowercase) - 1)]
            . $numbers[random_int(0, strlen($numbers) - 1)]
            . $special[random_int(0, strlen($special) - 1)];

        // Fill rest with random characters from all pools
        $allChars = $uppercase . $lowercase . $numbers . $special;
        for ($i = 4; $i < $length; $i++) {
            $password .= $allChars[random_int(0, strlen($allChars) - 1)];
        }

        // Shuffle the password
        return str_shuffle($password);
    }

    public static function configure(Schema $schema): Schema
    {
        return $schema
            ->columns(1)
            ->components([
                Section::make(__('User Information'))
                    ->schema([
                        TextInput::make('name')
                            ->label(__('Name'))
                            ->required()
                            ->maxLength(255),

                        TextInput::make('username')
                            ->label(__('Username'))
                            ->required()
                            ->maxLength(32)
                            ->alphaNum()
                            ->unique(ignoreRecord: true)
                            ->rules(['regex:/^[a-z][a-z0-9_]{0,31}$/'])
                            ->helperText(__('Lowercase letters, numbers, and underscores only. Must start with a letter.'))
                            ->disabled(fn (string $operation): bool => $operation === 'edit'),

                        TextInput::make('email')
                            ->label(__('Email address'))
                            ->email()
                            ->required()
                            ->unique(ignoreRecord: true)
                            ->maxLength(255),

                        TextInput::make('password')
                            ->password()
                            ->revealable()
                            ->dehydrateStateUsing(fn ($state) => filled($state) ? Hash::make($state) : null)
                            ->dehydrated(fn ($state) => filled($state))
                            ->required(fn (string $operation): bool => $operation === 'create')
                            ->minLength(8)
                            ->rules([
                                'regex:/[a-z]/',      // lowercase
                                'regex:/[A-Z]/',      // uppercase
                                'regex:/[0-9]/',      // number
                            ])
                            ->suffixActions([
                                Action::make('generatePassword')
                                    ->icon('heroicon-o-arrow-path')
                                    ->tooltip(__('Generate secure password'))
                                    ->action(function ($set) {
                                        $password = self::generateSecurePassword();
                                        $set('password', $password);
                                    }),
                                Action::make('copyPassword')
                                    ->icon('heroicon-o-clipboard-document')
                                    ->tooltip(__('Copy to clipboard'))
                                    ->action(function ($state, $livewire) {
                                        if ($state) {
                                            $escaped = addslashes($state);
                                            $livewire->js("navigator.clipboard.writeText('{$escaped}')");
                                            \Filament\Notifications\Notification::make()
                                                ->title(__('Copied to clipboard'))
                                                ->success()
                                                ->duration(2000)
                                                ->send();
                                        }
                                    }),
                            ])
                            ->helperText(__('Minimum 8 characters with uppercase, lowercase, and numbers'))
                            ->label(fn (string $operation): string => $operation === 'create' ? __('Password') : __('New Password')),
                    ])
                    ->columns(2),

                Section::make(__('Account Settings'))
                    ->schema([
                        Toggle::make('is_admin')
                            ->label(__('Administrator'))
                            ->helperText(__('Grant full administrative access'))
                            ->inline(false),

                        Toggle::make('is_active')
                            ->label(__('Active'))
                            ->default(true)
                            ->helperText(__('Inactive users cannot log in'))
                            ->inline(false),

                        Toggle::make('create_linux_user')
                            ->label(__('Create Linux User'))
                            ->default(true)
                            ->helperText(__('Create a system user account'))
                            ->visibleOn('create')
                            ->dehydrated(false)
                            ->inline(false),

                        DateTimePicker::make('email_verified_at')
                            ->label(__('Email Verified At')),
                    ])
                    ->columns(4),

                Section::make(__('Disk Quota'))
                    ->schema([
                        Placeholder::make('current_usage')
                            ->label(__('Current Usage'))
                            ->content(function ($record) {
                                if (!$record) {
                                    return __('N/A');
                                }

                                $used = $record->disk_usage_formatted;
                                $quotaMb = $record->disk_quota_mb;

                                if (!$quotaMb || $quotaMb <= 0) {
                                    return "{$used} (" . __('Unlimited') . ")";
                                }

                                $quota = $quotaMb >= 1024
                                    ? number_format($quotaMb / 1024, 1) . ' GB'
                                    : $quotaMb . ' MB';
                                $percent = $record->disk_usage_percent;

                                return "{$used} / {$quota} ({$percent}%)";
                            })
                            ->visibleOn('edit'),

                        Toggle::make('unlimited_quota')
                            ->label(__('Unlimited Quota'))
                            ->helperText(__('No disk space limit'))
                            ->default(fn () => (int) DnsSetting::get('default_quota_mb', 5120) === 0)
                            ->live()
                            ->afterStateHydrated(function (Toggle $component, $state, $record) {
                                if ($record) {
                                    $component->state(!$record->disk_quota_mb || $record->disk_quota_mb <= 0);
                                }
                            })
                            ->afterStateUpdated(function ($state, callable $set) {
                                if ($state) {
                                    $set('disk_quota_mb', 0);
                                } else {
                                    $set('disk_quota_mb', (int) DnsSetting::get('default_quota_mb', 5120));
                                }
                            })
                            ->inline(false),

                        TextInput::make('disk_quota_mb')
                            ->label(__('Disk Quota'))
                            ->numeric()
                            ->minValue(1)
                            ->default(fn () => (int) DnsSetting::get('default_quota_mb', 5120))
                            ->helperText(fn ($state) => $state && $state > 0 ? number_format($state / 1024, 1) . ' GB' : null)
                            ->suffix('MB')
                            ->visible(fn ($get) => !$get('unlimited_quota'))
                            ->required(fn ($get) => !$get('unlimited_quota')),
                    ])
                    ->description(fn () => !(bool) DnsSetting::get('quotas_enabled', false) ? __('Note: Quotas are currently disabled in Server Settings.') : null)
                    ->columns(3),

                Section::make(__('System Information'))
                    ->schema([
                        Placeholder::make('home_directory_display')
                            ->label(__('Home Directory'))
                            ->content(fn ($record) => $record?->home_directory ?? '/home/' . __('username')),

                        Placeholder::make('created_at_display')
                            ->label(__('Created'))
                            ->content(fn ($record) => $record?->created_at?->format('M d, Y H:i') ?? __('N/A')),

                        Placeholder::make('updated_at_display')
                            ->label(__('Last Updated'))
                            ->content(fn ($record) => $record?->updated_at?->format('M d, Y H:i') ?? __('N/A')),
                    ])
                    ->columns(3)
                    ->visibleOn('edit')
                    ->collapsible(),
            ]);
    }
}
