<?php

declare(strict_types=1);

namespace App\Filament\Jabali\Pages;

use App\Models\Domain;
use App\Models\DomainAlias;
use App\Models\DomainHotlinkSetting;
use App\Models\DomainRedirect;
use App\Services\Agent\AgentClient;
use BackedEnum;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Radio;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Grid;
use Filament\Support\Enums\Width;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Facades\Auth;

class Domains extends Page implements HasActions, HasForms, HasTable
{
    use InteractsWithActions;
    use InteractsWithForms;
    use InteractsWithTable;

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-globe-alt';

    public static function getNavigationLabel(): string
    {
        return __('Domains');
    }

    protected static ?int $navigationSort = 2;

    protected string $view = 'filament.jabali.pages.domains';

    protected ?AgentClient $agent = null;

    public function getTitle(): string|Htmlable
    {
        return __('Domains');
    }

    public function getAgent(): AgentClient
    {
        if ($this->agent === null) {
            $this->agent = new AgentClient;
        }

        return $this->agent;
    }

    public function getUsername(): string
    {
        return Auth::user()->username;
    }

    public function table(Table $table): Table
    {
        return $table
            ->query(Domain::query()->where('user_id', Auth::id()))
            ->columns([
                TextColumn::make('domain')
                    ->label(__('Domain'))
                    ->icon('heroicon-o-globe-alt')
                    ->iconColor('primary')
                    ->description(fn (Domain $record) => $record->document_root)
                    ->url(fn (Domain $record) => 'http://'.$record->domain, shouldOpenInNewTab: true)
                    ->searchable()
                    ->sortable(),
                IconColumn::make('is_active')
                    ->label(__('Status'))
                    ->boolean()
                    ->trueIcon('heroicon-o-check-circle')
                    ->falseIcon('heroicon-o-x-circle')
                    ->trueColor('success')
                    ->falseColor('danger'),
                IconColumn::make('ssl_enabled')
                    ->label(__('SSL'))
                    ->boolean()
                    ->trueIcon('heroicon-m-lock-closed')
                    ->falseIcon('heroicon-m-lock-open')
                    ->trueColor('success')
                    ->falseColor('warning'),
                IconColumn::make('page_cache_enabled')
                    ->label(__('Page Cache'))
                    ->boolean()
                    ->trueIcon('heroicon-o-bolt')
                    ->falseIcon('heroicon-o-bolt-slash')
                    ->trueColor('success')
                    ->falseColor('gray'),
                TextColumn::make('redirects_count')
                    ->label(__('Redirects'))
                    ->counts('redirects')
                    ->badge()
                    ->color('info'),
                TextColumn::make('created_at')
                    ->label(__('Created'))
                    ->date('M d, Y')
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->recordActions([
                ActionGroup::make([
                    Action::make('files')
                        ->label(__('Files'))
                        ->icon('heroicon-o-folder')
                        ->color('info')
                        ->action(fn (Domain $record) => $this->openFileManager($record)),
                    Action::make('redirects')
                        ->label(__('Redirects'))
                        ->icon('heroicon-o-arrow-right-circle')
                        ->color('warning')
                        ->modalHeading(fn (Domain $record) => __('Redirects for :domain', ['domain' => $record->domain]))
                        ->modalDescription(__('Redirect this domain to another domain or set up page redirects'))
                        ->modalWidth(Width::FourExtraLarge)
                        ->modalSubmitActionLabel(__('Save Redirects'))
                        ->form(fn (Domain $record) => $this->getRedirectsForm($record))
                        ->fillForm(fn (Domain $record) => $this->getRedirectsFormData($record))
                        ->action(fn (Domain $record, array $data) => $this->saveRedirects($record, $data)),
                    Action::make('aliases')
                        ->label(__('Aliases'))
                        ->icon('heroicon-o-link')
                        ->color('info')
                        ->modalHeading(fn (Domain $record) => __('Aliases for :domain', ['domain' => $record->domain]))
                        ->modalDescription(__('Point additional domains to the same website content.'))
                        ->modalWidth(Width::Large)
                        ->modalSubmitActionLabel(__('Save Aliases'))
                        ->form(fn (Domain $record) => $this->getAliasesForm($record))
                        ->fillForm(fn (Domain $record) => $this->getAliasesFormData($record))
                        ->action(fn (Domain $record, array $data) => $this->saveAliases($record, $data)),
                    Action::make('errorPages')
                        ->label(__('Error Pages'))
                        ->icon('heroicon-o-document-text')
                        ->color('gray')
                        ->modalHeading(fn (Domain $record) => __('Custom Error Pages for :domain', ['domain' => $record->domain]))
                        ->modalDescription(__('Customize the 404, 500 and 503 pages shown to visitors.'))
                        ->modalWidth(Width::TwoExtraLarge)
                        ->modalSubmitActionLabel(__('Save Error Pages'))
                        ->form(fn (Domain $record) => $this->getErrorPagesForm())
                        ->fillForm(fn (Domain $record) => $this->getErrorPagesFormData($record))
                        ->action(fn (Domain $record, array $data) => $this->saveErrorPages($record, $data)),
                    Action::make('hotlink')
                        ->label(__('Hotlink Protection'))
                        ->icon('heroicon-o-shield-check')
                        ->color('success')
                        ->modalHeading(fn (Domain $record) => __('Hotlink Protection for :domain', ['domain' => $record->domain]))
                        ->modalDescription(__('Prevent other websites from directly linking to your files'))
                        ->modalWidth(Width::TwoExtraLarge)
                        ->form($this->getHotlinkForm())
                        ->fillForm(fn (Domain $record) => $this->getHotlinkFormData($record))
                        ->action(fn (Domain $record, array $data) => $this->saveHotlinkSettings($record, $data)),
                    Action::make('index')
                        ->label(__('Index Manager'))
                        ->icon('heroicon-o-document-text')
                        ->color('gray')
                        ->modalHeading(fn (Domain $record) => __('Index Manager for :domain', ['domain' => $record->domain]))
                        ->modalDescription(__('Set the default directory index files'))
                        ->modalWidth(Width::Medium)
                        ->form($this->getIndexForm())
                        ->fillForm(fn (Domain $record) => ['directory_index' => $record->directory_index])
                        ->action(fn (Domain $record, array $data) => $this->saveIndexSettings($record, $data)),
                ])
                    ->label(__('Settings'))
                    ->icon('heroicon-o-cog-6-tooth')
                    ->color('gray')
                    ->button(),
                Action::make('toggle')
                    ->label(fn (Domain $record) => $record->is_active ? __('Disable') : __('Enable'))
                    ->icon(fn (Domain $record) => $record->is_active ? 'heroicon-o-no-symbol' : 'heroicon-o-check')
                    ->color(fn (Domain $record) => $record->is_active ? 'warning' : 'success')
                    ->action(fn (Domain $record) => $this->toggleDomain($record)),
                Action::make('delete')
                    ->label(__('Delete'))
                    ->icon('heroicon-o-trash')
                    ->color('danger')
                    ->requiresConfirmation()
                    ->modalHeading(__('Delete Domain'))
                    ->modalDescription(fn (Domain $record) => __('Are you sure you want to delete')." '{$record->domain}'? ".__('This will also delete the following associated data:'))
                    ->modalIcon('heroicon-o-trash')
                    ->modalIconColor('danger')
                    ->modalSubmitActionLabel(__('Delete Domain'))
                    ->modalWidth(Width::Large)
                    ->form(fn (Domain $record): array => [
                        Toggle::make('delete_files')
                            ->label(__('Delete all domain files'))
                            ->helperText(__('Permanently delete all files in the domain folder'))
                            ->default(true),
                        Toggle::make('delete_dns')
                            ->label(__('Delete DNS records').' ('.$record->dnsRecords()->count().')')
                            ->helperText(__('Remove all DNS records for this domain'))
                            ->default(true)
                            ->visible(fn () => $record->dnsRecords()->exists()),
                        Toggle::make('delete_email')
                            ->label(__('Delete email accounts').' ('.($record->emailDomain?->mailboxes()->count() ?? 0).')')
                            ->helperText(__('Remove all mailboxes and email configuration'))
                            ->default(true)
                            ->visible(fn () => $record->emailDomain()->exists()),
                        Toggle::make('delete_ssl')
                            ->label(__('Delete SSL certificate'))
                            ->helperText(__('Remove SSL certificate for this domain'))
                            ->default(true)
                            ->visible(fn () => $record->sslCertificate()->exists()),
                        Toggle::make('delete_wordpress')
                            ->label(__('Delete WordPress sites'))
                            ->helperText(__('Remove all WordPress installations on this domain'))
                            ->default(true),
                    ])
                    ->action(fn (Domain $record, array $data) => $this->deleteDomain($record, $data)),
            ])
            ->emptyStateHeading(__('No domains yet'))
            ->emptyStateDescription(__('Click "Add Domain" to add your first domain'))
            ->emptyStateIcon('heroicon-o-globe-alt')
            ->striped()
            ->defaultSort('created_at', 'desc');
    }

    protected function getRedirectsForm(Domain $record): array
    {
        return [
            // Domain-wide redirect
            Toggle::make('domain_redirect_enabled')
                ->label(__('Redirect Entire Domain'))
                ->helperText(__('Redirect all traffic from this domain to another domain'))
                ->live()
                ->columnSpanFull(),

            Grid::make()
                ->schema([
                    TextInput::make('domain_redirect_url')
                        ->label(__('Redirect To'))
                        ->placeholder('https://newdomain.com')
                        ->helperText(__('All requests to this domain will be redirected to this URL'))
                        ->url()
                        ->required(fn ($get) => $get('domain_redirect_enabled'))
                        ->columnSpan(['default' => 2, 'md' => 1]),
                    Select::make('domain_redirect_type')
                        ->label(__('Redirect Type'))
                        ->options([
                            '301' => __('Permanent (301) - SEO friendly'),
                            '302' => __('Temporary (302)'),
                        ])
                        ->default('301')
                        ->required(fn ($get) => $get('domain_redirect_enabled'))
                        ->columnSpan(['default' => 2, 'md' => 1]),
                ])
                ->columns(['default' => 2, 'md' => 2])
                ->visible(fn ($get) => $get('domain_redirect_enabled')),

            // Page redirects
            Repeater::make('redirects')
                ->label(__('Page Redirects'))
                ->helperText(__('Redirect specific paths to other URLs'))
                ->schema([
                    Grid::make()
                        ->schema([
                            TextInput::make('source_path')
                                ->label(__('Source Path'))
                                ->placeholder('/old-page')
                                ->helperText(__('Path to redirect from (e.g., /old-page)'))
                                ->required()
                                ->columnSpan(['default' => 2, 'md' => 1]),
                            TextInput::make('destination_url')
                                ->label(__('Destination URL'))
                                ->placeholder('https://example.com/new-page')
                                ->helperText(__('Full URL to redirect to'))
                                ->required()
                                ->url()
                                ->columnSpan(['default' => 2, 'md' => 1]),
                        ])
                        ->columns(['default' => 2, 'md' => 2]),
                    Grid::make()
                        ->schema([
                            Select::make('redirect_type')
                                ->label(__('Type'))
                                ->options([
                                    '301' => __('Permanent (301)'),
                                    '302' => __('Temporary (302)'),
                                ])
                                ->default('301')
                                ->required()
                                ->columnSpan(['default' => 2, 'sm' => 1]),
                            Toggle::make('is_wildcard')
                                ->label(__('Wildcard'))
                                ->helperText(__('Match all paths starting with source'))
                                ->columnSpan(['default' => 2, 'sm' => 1]),
                            Toggle::make('is_active')
                                ->label(__('Active'))
                                ->default(true)
                                ->columnSpan(['default' => 2, 'sm' => 1]),
                        ])
                        ->columns(['default' => 2, 'sm' => 3]),
                ])
                ->itemLabel(fn (array $state): ?string => ($state['source_path'] ?? '').' → '.($state['redirect_type'] ?? '301'))
                ->collapsible()
                ->collapsed(fn () => $record->redirects()->count() > 3)
                ->addActionLabel(__('Add Page Redirect'))
                ->reorderable()
                ->defaultItems(0)
                ->visible(fn ($get) => ! $get('domain_redirect_enabled')),
        ];
    }

    protected function getRedirectsFormData(Domain $record): array
    {
        // Check if there's a domain-wide redirect (source_path = '/*' or '*')
        $domainRedirect = $record->redirects()
            ->whereIn('source_path', ['/*', '*', '/'])
            ->where('is_wildcard', true)
            ->first();

        return [
            'domain_redirect_enabled' => $domainRedirect !== null,
            'domain_redirect_url' => $domainRedirect?->destination_url ?? '',
            'domain_redirect_type' => $domainRedirect?->redirect_type ?? '301',
            'redirects' => $record->redirects()
                ->whereNotIn('source_path', ['/*', '*', '/'])
                ->orWhere('is_wildcard', false)
                ->get()
                ->map(fn ($r) => [
                    'id' => $r->id,
                    'source_path' => $r->source_path,
                    'destination_url' => $r->destination_url,
                    'redirect_type' => $r->redirect_type,
                    'is_wildcard' => $r->is_wildcard,
                    'is_active' => $r->is_active,
                ])->toArray(),
        ];
    }

    protected function getHotlinkForm(): array
    {
        return [
            Toggle::make('is_enabled')
                ->label(__('Enable Hotlink Protection'))
                ->helperText(__('Block other websites from directly linking to your images and files'))
                ->live(),
            Grid::make()
                ->schema([
                    Textarea::make('allowed_domains')
                        ->label(__('Allowed Domains'))
                        ->helperText(__('One domain per line that can link to your files (your own domain is always allowed)'))
                        ->placeholder("example.com\ntrusted-site.com")
                        ->rows(4)
                        ->columnSpan(['default' => 2, 'md' => 1]),
                    TextInput::make('protected_extensions')
                        ->label(__('Protected File Extensions'))
                        ->helperText(__('Comma-separated list of file extensions to protect'))
                        ->placeholder('jpg,jpeg,png,gif,webp,svg,mp4,mp3,pdf')
                        ->default(DomainHotlinkSetting::getDefaultExtensions())
                        ->columnSpan(['default' => 2, 'md' => 1]),
                ])
                ->columns(['default' => 2, 'md' => 2])
                ->visible(fn ($get) => $get('is_enabled')),
            Grid::make()
                ->schema([
                    Toggle::make('block_blank_referrer')
                        ->label(__('Block Blank Referrer'))
                        ->helperText(__('Block requests with no referrer header'))
                        ->default(true)
                        ->columnSpan(['default' => 2, 'md' => 1]),
                    TextInput::make('redirect_url')
                        ->label(__('Redirect URL (Optional)'))
                        ->helperText(__('Redirect blocked requests to this URL instead of showing an error'))
                        ->placeholder('https://example.com/hotlink-blocked.png')
                        ->url()
                        ->columnSpan(['default' => 2, 'md' => 1]),
                ])
                ->columns(['default' => 2, 'md' => 2])
                ->visible(fn ($get) => $get('is_enabled')),
        ];
    }

    protected function getHotlinkFormData(Domain $record): array
    {
        $setting = $record->hotlinkSetting;
        if (! $setting) {
            return [
                'is_enabled' => false,
                'allowed_domains' => '',
                'block_blank_referrer' => true,
                'protected_extensions' => DomainHotlinkSetting::getDefaultExtensions(),
                'redirect_url' => '',
            ];
        }

        return [
            'is_enabled' => $setting->is_enabled,
            'allowed_domains' => $setting->allowed_domains,
            'block_blank_referrer' => $setting->block_blank_referrer,
            'protected_extensions' => $setting->protected_extensions,
            'redirect_url' => $setting->redirect_url ?? '',
        ];
    }

    protected function getIndexForm(): array
    {
        return [
            Radio::make('directory_index')
                ->label(__('Directory Index Priority'))
                ->helperText(__('Choose which file should be served as the default index'))
                ->options([
                    'index.php index.html' => __('PHP first (index.php, then index.html)'),
                    'index.html index.php' => __('HTML first (index.html, then index.php)'),
                    'index.php' => __('PHP only (index.php)'),
                    'index.html' => __('HTML only (index.html)'),
                    'index.php index.html index.htm' => __('PHP, HTML, HTM (full support)'),
                ])
                ->default('index.php index.html')
                ->required(),
        ];
    }

    protected function getHeaderActions(): array
    {
        return [
            $this->createDomainAction(),
        ];
    }

    protected function createDomainAction(): Action
    {
        return Action::make('createDomain')
            ->label(__('Add Domain'))
            ->icon('heroicon-o-plus-circle')
            ->color('primary')
            ->modalHeading(__('Add Domain'))
            ->modalDescription(__('Add a new domain to your hosting account'))
            ->modalIcon('heroicon-o-globe-alt')
            ->modalIconColor('primary')
            ->modalSubmitActionLabel(__('Add Domain'))
            ->form([
                TextInput::make('domain')
                    ->label(__('Domain Name'))
                    ->placeholder(__('example.com'))
                    ->required()
                    ->regex('/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$/')
                    ->helperText(__('Enter the domain name without http:// or www')),
            ])
            ->action(function (array $data): void {
                try {
                    $user = Auth::user();
                    $limit = $user?->hostingPackage?->domains_limit;
                    if ($limit && Domain::where('user_id', $user->id)->count() >= $limit) {
                        Notification::make()
                            ->title(__('Domain limit reached'))
                            ->body(__('Your hosting package allows up to :limit domains.', ['limit' => $limit]))
                            ->warning()
                            ->send();

                        return;
                    }

                    $result = $this->getAgent()->domainCreate($this->getUsername(), $data['domain']);

                    if ($result['success'] ?? false) {
                        Domain::create([
                            'user_id' => Auth::id(),
                            'domain' => $data['domain'],
                            'document_root' => '/home/'.$this->getUsername().'/domains/'.$data['domain'].'/public_html',
                            'is_active' => true,
                            'ssl_enabled' => false,
                            'directory_index' => 'index.php index.html',
                            'page_cache_enabled' => false,
                        ]);

                        Notification::make()
                            ->title(__('Domain created!'))
                            ->body(__('Your domain is now active.'))
                            ->success()
                            ->send();
                    } else {
                        throw new Exception($result['error'] ?? 'Unknown error');
                    }
                } catch (Exception $e) {
                    Notification::make()
                        ->title(__('Error creating domain'))
                        ->body($e->getMessage())
                        ->danger()
                        ->send();
                }
            });
    }

    public function saveRedirects(Domain $domain, array $data): void
    {
        try {
            $existingIds = [];

            // Handle domain-wide redirect
            if ($data['domain_redirect_enabled'] ?? false) {
                // Delete all existing redirects and create a single domain-wide redirect
                $domain->redirects()->delete();

                $redirect = $domain->redirects()->create([
                    'source_path' => '/*',
                    'destination_url' => $data['domain_redirect_url'],
                    'redirect_type' => $data['domain_redirect_type'] ?? '301',
                    'is_wildcard' => true,
                    'is_active' => true,
                ]);
                $existingIds[] = $redirect->id;
            } else {
                // Delete any domain-wide redirects
                $domain->redirects()
                    ->whereIn('source_path', ['/*', '*', '/'])
                    ->where('is_wildcard', true)
                    ->delete();

                // Handle page redirects
                $redirectsData = $data['redirects'] ?? [];

                foreach ($redirectsData as $redirectData) {
                    if (! empty($redirectData['id'])) {
                        $redirect = DomainRedirect::find($redirectData['id']);
                        if ($redirect && $redirect->domain_id === $domain->id) {
                            $redirect->update([
                                'source_path' => $redirectData['source_path'],
                                'destination_url' => $redirectData['destination_url'],
                                'redirect_type' => $redirectData['redirect_type'],
                                'is_wildcard' => $redirectData['is_wildcard'] ?? false,
                                'is_active' => $redirectData['is_active'] ?? true,
                            ]);
                            $existingIds[] = $redirect->id;
                        }
                    } else {
                        $redirect = $domain->redirects()->create([
                            'source_path' => $redirectData['source_path'],
                            'destination_url' => $redirectData['destination_url'],
                            'redirect_type' => $redirectData['redirect_type'],
                            'is_wildcard' => $redirectData['is_wildcard'] ?? false,
                            'is_active' => $redirectData['is_active'] ?? true,
                        ]);
                        $existingIds[] = $redirect->id;
                    }
                }

                // Delete removed page redirects (but not domain-wide ones which we already handled)
                if (! empty($existingIds)) {
                    $domain->redirects()
                        ->whereNotIn('id', $existingIds)
                        ->whereNotIn('source_path', ['/*', '*', '/'])
                        ->delete();
                }
            }

            // Apply redirects via agent
            $this->applyRedirects($domain);

            Notification::make()
                ->title(__('Redirects saved!'))
                ->body(__('Your redirect rules have been updated.'))
                ->success()
                ->send();
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Error saving redirects'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
    }

    protected function applyRedirects(Domain $domain): void
    {
        $redirects = $domain->redirects()->where('is_active', true)->get()->map(fn ($r) => [
            'source' => $r->source_path,
            'destination' => $r->destination_url,
            'type' => $r->redirect_type,
            'wildcard' => $r->is_wildcard,
        ])->toArray();

        $this->getAgent()->send('domain.set_redirects', [
            'username' => $this->getUsername(),
            'domain' => $domain->domain,
            'redirects' => $redirects,
        ]);
    }

    public function saveHotlinkSettings(Domain $domain, array $data): void
    {
        try {
            $setting = $domain->hotlinkSetting;
            if (! $setting) {
                $setting = new DomainHotlinkSetting(['domain_id' => $domain->id]);
            }

            $setting->fill([
                'is_enabled' => $data['is_enabled'] ?? false,
                'allowed_domains' => $data['allowed_domains'] ?? '',
                'block_blank_referrer' => $data['block_blank_referrer'] ?? true,
                'protected_extensions' => $data['protected_extensions'] ?? DomainHotlinkSetting::getDefaultExtensions(),
                'redirect_url' => $data['redirect_url'] ?? null,
            ]);
            $setting->save();

            // Apply hotlink protection via agent
            $this->getAgent()->send('domain.set_hotlink_protection', [
                'username' => $this->getUsername(),
                'domain' => $domain->domain,
                'enabled' => $setting->is_enabled,
                'allowed_domains' => $setting->getAllowedDomainsArray(),
                'block_blank_referrer' => $setting->block_blank_referrer,
                'protected_extensions' => $setting->getProtectedExtensionsArray(),
                'redirect_url' => $setting->redirect_url,
            ]);

            Notification::make()
                ->title(__('Hotlink protection updated!'))
                ->body($setting->is_enabled ? __('Protection is now active.') : __('Protection has been disabled.'))
                ->success()
                ->send();
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Error saving hotlink settings'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
    }

    public function saveIndexSettings(Domain $domain, array $data): void
    {
        try {
            $domain->update(['directory_index' => $data['directory_index']]);

            // Apply index settings via agent
            $this->getAgent()->send('domain.set_directory_index', [
                'username' => $this->getUsername(),
                'domain' => $domain->domain,
                'directory_index' => $data['directory_index'],
            ]);

            Notification::make()
                ->title(__('Index settings updated!'))
                ->body(__('Directory index priority has been changed.'))
                ->success()
                ->send();
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Error saving index settings'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
    }

    public function toggleDomain(Domain $domain): void
    {
        try {
            $newStatus = ! $domain->is_active;
            $result = $this->getAgent()->domainToggle($this->getUsername(), $domain->domain, $newStatus);

            if ($result['success'] ?? false) {
                $domain->update(['is_active' => $newStatus]);

                $status = $newStatus ? __('Enabled') : __('Disabled');
                Notification::make()
                    ->title(__('Domain')." {$status}")
                    ->success()
                    ->send();
            } else {
                throw new Exception($result['error'] ?? 'Unknown error');
            }
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Error toggling domain'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
    }

    public function deleteDomain(Domain $domain, array $options): void
    {
        $deletedItems = [];
        $errors = [];

        try {
            // Delete WordPress sites first (via Agent)
            if ($options['delete_wordpress'] ?? false) {
                try {
                    $wpResult = $this->getAgent()->send('wp.list', [
                        'username' => $this->getUsername(),
                    ]);

                    foreach ($wpResult['sites'] ?? [] as $site) {
                        if (($site['domain'] ?? '') === $domain->domain) {
                            $this->getAgent()->send('wp.delete', [
                                'username' => $this->getUsername(),
                                'site_id' => $site['id'],
                                'delete_files' => true,
                                'delete_database' => true,
                            ]);
                            $deletedItems[] = __('WordPress site');
                        }
                    }
                } catch (Exception $e) {
                    $errors[] = __('WordPress: ').$e->getMessage();
                }
            }

            // Delete SSL certificate
            if ($options['delete_ssl'] ?? false) {
                if ($domain->sslCertificate) {
                    try {
                        $this->getAgent()->send('ssl.delete', [
                            'username' => $this->getUsername(),
                            'domain' => $domain->domain,
                        ]);
                        $domain->sslCertificate->delete();
                        $deletedItems[] = __('SSL certificate');
                    } catch (Exception $e) {
                        $errors[] = __('SSL: ').$e->getMessage();
                    }
                }
            }

            // Delete email accounts
            if ($options['delete_email'] ?? false) {
                if ($domain->emailDomain) {
                    try {
                        foreach ($domain->emailDomain->mailboxes as $mailbox) {
                            $this->getAgent()->send('email.mailbox_delete', [
                                'username' => $this->getUsername(),
                                'email' => $mailbox->email,
                                'delete_files' => true,
                                'maildir_path' => $mailbox->maildir_path,
                            ]);
                        }
                        $this->getAgent()->send('email.disable_domain', [
                            'username' => $this->getUsername(),
                            'domain' => $domain->domain,
                        ]);

                        $mailboxCount = $domain->emailDomain->mailboxes()->count();
                        $domain->emailDomain->mailboxes()->delete();
                        $domain->emailDomain->delete();
                        $deletedItems[] = __(':count email account(s)', ['count' => $mailboxCount]);
                    } catch (Exception $e) {
                        $errors[] = __('Email: ').$e->getMessage();
                    }
                }
            }

            // Delete DNS records
            if ($options['delete_dns'] ?? false) {
                try {
                    $dnsCount = $domain->dnsRecords()->count();
                    if ($dnsCount > 0) {
                        $this->getAgent()->send('dns.delete_zone', [
                            'domain' => $domain->domain,
                        ]);
                        $domain->dnsRecords()->delete();
                        $deletedItems[] = __(':count DNS record(s)', ['count' => $dnsCount]);
                    }
                } catch (Exception $e) {
                    $errors[] = __('DNS: ').$e->getMessage();
                }
            }

            // Delete redirects and hotlink settings (cascade should handle this, but be explicit)
            $domain->redirects()->delete();
            $domain->hotlinkSetting?->delete();

            // Delete domain files and configuration via Agent
            $result = $this->getAgent()->domainDelete(
                $this->getUsername(),
                $domain->domain,
                $options['delete_files'] ?? false
            );

            if ($result['success'] ?? false) {
                $domain->delete();

                $message = __('Domain deleted successfully.');
                if (! empty($deletedItems)) {
                    $message .= ' '.__('Also deleted: ').implode(', ', $deletedItems);
                }

                Notification::make()
                    ->title(__('Domain deleted'))
                    ->body($message)
                    ->success()
                    ->send();

                if (! empty($errors)) {
                    Notification::make()
                        ->title(__('Some items had warnings'))
                        ->body(implode("\n", $errors))
                        ->warning()
                        ->send();
                }
            } else {
                throw new Exception($result['error'] ?? 'Unknown error');
            }
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Error deleting domain'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
    }

    public function openFileManager(Domain $domain): void
    {
        $path = str_replace('/home/'.$this->getUsername().'/', '', $domain->document_root);
        $this->redirect(route('filament.jabali.pages.files', ['path' => $path]));
    }

    protected function getAliasesForm(Domain $record): array
    {
        return [
            Repeater::make('aliases')
                ->label(__('Domain Aliases'))
                ->schema([
                    TextInput::make('alias')
                        ->label(__('Alias Domain'))
                        ->placeholder('alias-example.com')
                        ->required()
                        ->rule('regex:/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*\\.[a-z]{2,}$/')
                        ->helperText(__('Enter a full domain name.')),
                ])
                ->addActionLabel(__('Add Alias'))
                ->columns(1)
                ->defaultItems(0),
        ];
    }

    protected function getAliasesFormData(Domain $record): array
    {
        return [
            'aliases' => $record->aliases()
                ->orderBy('alias')
                ->get()
                ->map(fn (DomainAlias $alias) => ['alias' => $alias->alias])
                ->toArray(),
        ];
    }

    protected function saveAliases(Domain $record, array $data): void
    {
        $aliases = collect($data['aliases'] ?? [])
            ->pluck('alias')
            ->map(fn ($alias) => strtolower(trim((string) $alias)))
            ->filter()
            ->unique()
            ->values();

        $existing = $record->aliases()->pluck('alias')->map(fn ($alias) => strtolower($alias));

        $toAdd = $aliases->diff($existing);
        $toRemove = $existing->diff($aliases);

        $errors = [];

        foreach ($toAdd as $alias) {
            try {
                $result = $this->getAgent()->domainAliasAdd($this->getUsername(), $record->domain, $alias);
                if (! ($result['success'] ?? false)) {
                    throw new Exception($result['error'] ?? 'Failed to add alias');
                }
                DomainAlias::firstOrCreate([
                    'domain_id' => $record->id,
                    'alias' => $alias,
                ]);
            } catch (Exception $e) {
                $errors[] = $alias.': '.$e->getMessage();
            }
        }

        foreach ($toRemove as $alias) {
            try {
                $result = $this->getAgent()->domainAliasRemove($this->getUsername(), $record->domain, $alias);
                if (! ($result['success'] ?? false)) {
                    throw new Exception($result['error'] ?? 'Failed to remove alias');
                }
                $record->aliases()->where('alias', $alias)->delete();
            } catch (Exception $e) {
                $errors[] = $alias.': '.$e->getMessage();
            }
        }

        if (! empty($errors)) {
            Notification::make()
                ->title(__('Some aliases failed'))
                ->body(implode("\n", $errors))
                ->warning()
                ->send();

            return;
        }

        Notification::make()
            ->title(__('Aliases updated'))
            ->success()
            ->send();
    }

    protected function getErrorPagesForm(): array
    {
        return [
            Textarea::make('page_404')
                ->label(__('404 Page (Not Found)'))
                ->rows(6)
                ->placeholder(__('HTML content for your 404 page')),
            Textarea::make('page_500')
                ->label(__('500 Page (Server Error)'))
                ->rows(6)
                ->placeholder(__('HTML content for your 500 page')),
            Textarea::make('page_503')
                ->label(__('503 Page (Maintenance)'))
                ->rows(6)
                ->placeholder(__('HTML content for your 503 page')),
        ];
    }

    protected function getErrorPagesFormData(Domain $record): array
    {
        return [
            'page_404' => $this->readErrorPageContent($record, '404.html'),
            'page_500' => $this->readErrorPageContent($record, '500.html'),
            'page_503' => $this->readErrorPageContent($record, '503.html'),
        ];
    }

    protected function saveErrorPages(Domain $record, array $data): void
    {
        try {
            $result = $this->getAgent()->domainEnsureErrorPages($this->getUsername(), $record->domain);
            if (! ($result['success'] ?? false)) {
                throw new Exception($result['error'] ?? 'Failed to enable error pages');
            }

            foreach (['404' => 'page_404', '500' => 'page_500', '503' => 'page_503'] as $code => $key) {
                $content = trim((string) ($data[$key] ?? ''));
                $path = $this->getErrorPagePath($record, "{$code}.html");

                if ($content === '') {
                    try {
                        $this->getAgent()->fileDelete($this->getUsername(), $path);
                    } catch (Exception) {
                        // Ignore missing file
                    }

                    continue;
                }

                $this->getAgent()->fileWrite($this->getUsername(), $path, $content);
            }

            Notification::make()
                ->title(__('Error pages updated'))
                ->success()
                ->send();
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Failed to update error pages'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
    }

    protected function readErrorPageContent(Domain $record, string $filename): string
    {
        $path = $this->getErrorPagePath($record, $filename);
        try {
            $result = $this->getAgent()->fileRead($this->getUsername(), $path);
            if ($result['success'] ?? false) {
                return (string) base64_decode($result['content'] ?? '');
            }
        } catch (Exception) {
            // ignore
        }

        return '';
    }

    protected function getErrorPagePath(Domain $record, string $filename): string
    {
        return "domains/{$record->domain}/public_html/{$filename}";
    }
}
