<?php

declare(strict_types=1);

namespace App\Filament\Admin\Pages;

use App\Filament\Admin\Widgets\Security\BannedIpsTable;
use App\Filament\Admin\Widgets\Security\Fail2banLogsTable;
use App\Filament\Admin\Widgets\Security\JailsTable;
use App\Filament\Admin\Widgets\Security\LynisResultsTable;
use App\Filament\Admin\Widgets\Security\NiktoResultsTable;
use App\Filament\Admin\Widgets\Security\QuarantinedFilesTable;
use App\Filament\Admin\Widgets\Security\ThreatsTable;
use App\Filament\Admin\Widgets\Security\WpscanResultsTable;
use App\Models\AuditLog;
use App\Services\Agent\AgentClient;
use BackedEnum;
use Exception;
use Filament\Actions\Action;
use Filament\Actions\Action as FormAction;
use Filament\Actions\Action as TableAction;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Select;
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\Actions as FormActions;
use Filament\Schemas\Components\EmbeddedTable;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Group;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Text;
use Filament\Schemas\Components\View;
use Filament\Schemas\Schema;
use Filament\Support\Enums\Alignment;
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 Livewire\Attributes\On;
use Livewire\Attributes\Url;

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

    protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-shield-check';

    protected static ?int $navigationSort = 5;

    protected static ?string $slug = 'security';

    protected string $view = 'filament.admin.pages.security';

    protected ?AgentClient $agent = null;

    // Firewall
    public bool $firewallInstalled = false;

    public bool $firewallEnabled = false;

    public array $firewallRules = [];

    public string $defaultIncoming = 'deny';

    public string $defaultOutgoing = 'allow';

    public string $firewallStatusText = '';

    public ?int $ruleToDelete = null;

    // Fail2ban
    public bool $fail2banInstalled = false;

    public bool $fail2banRunning = false;

    public string $fail2banVersion = '';

    public array $jails = [];

    public array $availableJails = [];

    public ?int $totalBanned = null;

    public array $fail2banLogs = [];

    public int $maxRetry = 5;

    public int $banTime = 600;

    public int $findTime = 600;

    // ClamAV
    public bool $clamavInstalled = false;

    public bool $clamavRunning = false;

    public string $clamavVersion = '';

    public int $signatureCount = 0;

    public string $lastUpdate = '';

    public bool $clamavLightMode = false;

    public array $signatureDatabases = [];

    public array $recentThreats = [];

    public array $quarantinedFiles = [];

    public bool $realtimeEnabled = false;

    public bool $realtimeRunning = false;

    // SSH Settings
    public bool $sshPasswordAuth = false;

    public bool $sshPubkeyAuth = true;

    public int $sshPort = 22;

    // Scanner properties
    public bool $lynisInstalled = false;

    public bool $wpscanInstalled = false;

    public bool $niktoInstalled = false;

    public string $lynisVersion = '';

    public string $wpscanVersion = '';

    public string $niktoVersion = '';

    public array $lynisResults = [];

    public array $wpscanResults = [];

    public array $niktoResults = [];

    public bool $isScanning = false;

    public string $currentScan = '';

    public string $scanOutput = '';

    public ?string $selectedWpSiteId = null;

    public ?array $data = [];

    public ?string $lastLynisScan = null;

    public ?string $lastWpscanScan = null;

    public ?string $lastNiktoScan = null;

    // ClamAV on-demand scan properties
    public ?string $selectedClamUser = null;

    public array $clamScanResults = [];

    public ?string $lastClamScan = null;

    #[Url(as: 'tab')]
    public ?string $activeTab = 'overview';

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

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

    protected function getAgent(): AgentClient
    {
        return $this->agent ??= new AgentClient;
    }

    protected function normalizeTabName(?string $tab): string
    {
        return match ($tab) {
            'overview', 'firewall', 'fail2ban', 'antivirus', 'ssh', 'scanner' => $tab,
            default => 'overview',
        };
    }

    public function setTab(string $tab): void
    {
        $this->activeTab = $this->normalizeTabName($tab);

        if ($this->activeTab === 'fail2ban') {
            $this->loadFail2banStatus();
        }

        if ($this->activeTab === 'antivirus') {
            $this->loadClamavStatus();
            $this->loadClamScanResults();
        }

        if ($this->activeTab === 'scanner') {
            $this->checkScannerToolStatus();
            $this->loadLastScans();
        }
    }

    public function mount(): void
    {
        $this->activeTab = $this->normalizeTabName($this->activeTab);
        $this->loadFirewallStatus();
        $this->loadFail2banStatusLight();
        $this->loadClamavStatusLight();
        $this->loadSshSettings();

        $this->data = [
            'selectedWpSiteId' => null,
            'selectedClamUser' => null,
        ];

        if ($this->activeTab === 'fail2ban') {
            $this->loadFail2banStatus();
        } elseif ($this->activeTab === 'antivirus') {
            $this->loadClamavStatus();
            $this->loadClamScanResults();
        } elseif ($this->activeTab === 'scanner') {
            $this->checkScannerToolStatus();
            $this->loadLastScans();
        }
    }

    #[On('refresh-security-data')]
    public function refreshSecurityData(): void
    {
        $this->loadFail2banStatus();
        $this->loadClamavStatus();
    }

    protected function getForms(): array
    {
        return [
            'securityForm',
        ];
    }

    public function table(Table $table): Table
    {
        return $table
            ->records(fn () => $this->firewallRules)
            ->columns([
                TextColumn::make('number')
                    ->label(__('#'))
                    ->sortable()
                    ->width('60px'),
                TextColumn::make('action')
                    ->label(__('Action'))
                    ->badge()
                    ->color(fn (string $state): string => match (strtoupper($state)) {
                        'ALLOW' => 'success',
                        'DENY' => 'danger',
                        'LIMIT' => 'warning',
                        default => 'gray',
                    })
                    ->formatStateUsing(fn (string $state): string => strtoupper($state)),
                TextColumn::make('to')
                    ->label(__('To'))
                    ->default('-'),
                TextColumn::make('from')
                    ->label(__('From'))
                    ->default(__('Anywhere'))
                    ->formatStateUsing(fn (?string $state): string => $state ?: __('Anywhere')),
                TextColumn::make('direction')
                    ->label(__('Direction'))
                    ->badge()
                    ->color('gray'),
            ])
            ->recordAction(null)
            ->recordUrl(null)
            ->striped()
            ->emptyStateHeading(__('No firewall rules'))
            ->emptyStateDescription(__('Use the buttons above to add rules.'))
            ->emptyStateIcon('heroicon-o-shield-exclamation')
            ->actions([
                TableAction::make('delete')
                    ->label(__('Delete'))
                    ->icon('heroicon-o-trash')
                    ->color('danger')
                    ->requiresConfirmation()
                    ->action(fn (array $record) => $this->deleteRule($record['number'] ?? null)),
            ]);
    }

    public function securityForm(Schema $schema): Schema
    {
        return $schema
            ->schema([
                View::make('filament.admin.components.security-tabs-nav'),
                ...$this->getTabContent(),
            ]);
    }

    protected function getTabContent(): array
    {
        return match ($this->activeTab) {
            'overview' => $this->overviewTabContent(),
            'firewall' => $this->firewallTabContent(),
            'fail2ban' => $this->fail2banTabContent(),
            'antivirus' => $this->antivirusTabContent(),
            'ssh' => $this->sshTabContent(),
            'scanner' => $this->scannerTabContent(),
            default => $this->overviewTabContent(),
        };
    }

    protected function overviewTabContent(): array
    {
        return [
            Grid::make(['default' => 1, 'sm' => 3])
                ->schema([
                    Section::make($this->firewallEnabled ? __('Active') : __('Inactive'))
                        ->description(__('Firewall'))
                        ->icon('heroicon-o-shield-check')
                        ->iconColor($this->firewallEnabled ? 'success' : 'danger'),
                    Section::make($this->totalBanned !== null ? (string) $this->totalBanned : __('N/A'))
                        ->description(__('IPs Banned'))
                        ->icon('heroicon-o-lock-closed')
                        ->iconColor($this->fail2banRunning ? 'success' : 'danger'),
                    Section::make((string) count($this->recentThreats))
                        ->description(__('Threats Detected'))
                        ->icon('heroicon-o-bug-ant')
                        ->iconColor($this->clamavInstalled ? 'success' : 'gray'),
                ]),
            Section::make(__('Quick Actions'))
                ->icon('heroicon-o-bolt')
                ->schema([
                    FormActions::make([
                        FormAction::make('installFirewall')
                            ->label(__('Install Firewall'))
                            ->action('installFirewall')
                            ->visible(fn () => ! $this->firewallInstalled),
                        FormAction::make('installFail2ban')
                            ->label(__('Install Fail2ban'))
                            ->action('installFail2ban')
                            ->visible(fn () => ! $this->fail2banInstalled),
                        FormAction::make('installClamav')
                            ->label(__('Install Antivirus'))
                            ->action('installClamav')
                            ->visible(fn () => ! $this->clamavInstalled),
                    ])->visible(fn () => ! $this->firewallInstalled || ! $this->fail2banInstalled || ! $this->clamavInstalled),
                    Text::make(__('All essential security tools are installed.'))
                        ->visible(fn () => $this->firewallInstalled && $this->fail2banInstalled),
                ]),
            Section::make(__('Recent Audit Logs'))
                ->icon('heroicon-o-clipboard-document-list')
                ->schema([
                    EmbeddedTable::make(\App\Filament\Admin\Widgets\Security\AuditLogsTable::class),
                ]),
        ];
    }

    protected function firewallTabContent(): array
    {
        return [
            // Not installed state
            Section::make()
                ->schema([
                    Text::make(__('UFW Firewall is not installed.')),
                    FormActions::make([
                        FormAction::make('installFirewall')
                            ->label(__('Install Firewall'))
                            ->action('installFirewall'),
                    ])->alignment(Alignment::Center),
                ])
                ->visible(fn () => ! $this->firewallInstalled),
            // Installed state
            Group::make([
                Section::make(__('Firewall Status'))
                    ->icon('heroicon-o-shield-check')
                    ->iconColor($this->firewallEnabled ? 'success' : 'danger')
                    ->schema([
                        Grid::make(['default' => 1, 'sm' => 2, 'lg' => 4])
                            ->schema([
                                Section::make($this->firewallEnabled ? __('ACTIVE') : __('INACTIVE'))
                                    ->description(__('Status'))
                                    ->icon('heroicon-o-signal')
                                    ->iconColor($this->firewallEnabled ? 'success' : 'danger'),
                                Section::make(strtoupper($this->defaultIncoming))
                                    ->description(__('Default Incoming'))
                                    ->icon('heroicon-o-arrow-down-circle')
                                    ->iconColor($this->defaultIncoming === 'deny' ? 'success' : 'warning'),
                                Section::make(strtoupper($this->defaultOutgoing))
                                    ->description(__('Default Outgoing'))
                                    ->icon('heroicon-o-arrow-up-circle')
                                    ->iconColor($this->defaultOutgoing === 'allow' ? 'success' : 'warning'),
                                Section::make((string) count($this->firewallRules))
                                    ->description(__('Active Rules'))
                                    ->icon('heroicon-o-queue-list')
                                    ->iconColor('gray'),
                            ]),
                        FormActions::make([
                            FormAction::make('toggleFirewall')
                                ->label(fn () => $this->firewallEnabled ? __('Disable Firewall') : __('Enable Firewall'))
                                ->icon(fn () => $this->firewallEnabled ? 'heroicon-o-x-circle' : 'heroicon-o-shield-check')
                                ->color(fn () => $this->firewallEnabled ? 'danger' : 'success')
                                ->action('toggleFirewall'),
                            FormAction::make('reloadFirewall')
                                ->label(__('Reload'))
                                ->icon('heroicon-o-arrow-path')
                                ->color('gray')
                                ->outlined()
                                ->action('reloadFirewall'),
                            FormAction::make('resetFirewall')
                                ->label(__('Reset All'))
                                ->icon('heroicon-o-trash')
                                ->color('danger')
                                ->outlined()
                                ->action('resetFirewall'),
                        ]),
                    ]),
                Section::make(__('Add Rule'))
                    ->icon('heroicon-o-plus-circle')
                    ->schema([
                        FormActions::make([
                            FormAction::make('allowPort')
                                ->label(__('Allow Port'))
                                ->icon('heroicon-o-plus-circle')
                                ->color('success')
                                ->action('openAllowPort'),
                            FormAction::make('denyPort')
                                ->label(__('Block Port'))
                                ->icon('heroicon-o-x-circle')
                                ->color('danger')
                                ->action('openDenyPort'),
                            FormAction::make('allowIp')
                                ->label(__('Allow IP'))
                                ->icon('heroicon-o-check-circle')
                                ->color('success')
                                ->action('openAllowIp'),
                            FormAction::make('denyIp')
                                ->label(__('Block IP'))
                                ->icon('heroicon-o-no-symbol')
                                ->color('danger')
                                ->action('openDenyIp'),
                            FormAction::make('allowService')
                                ->label(__('Allow Service'))
                                ->icon('heroicon-o-server')
                                ->color('info')
                                ->action('openAllowService'),
                            FormAction::make('limitPort')
                                ->label(__('Rate Limit'))
                                ->icon('heroicon-o-clock')
                                ->color('warning')
                                ->action('openLimitPort'),
                        ]),
                    ]),
                Section::make(__('Firewall Rules'))
                    ->icon('heroicon-o-queue-list')
                    ->schema([
                        EmbeddedTable::make(),
                    ]),
                Section::make(__('Quick Tips'))
                    ->icon('heroicon-o-light-bulb')
                    ->collapsible()
                    ->collapsed()
                    ->schema([
                        Text::make(__('Allow Port: Opens a port for all incoming connections (e.g., 80 for web, 443 for HTTPS)')),
                        Text::make(__('Block IP: Denies all traffic from a specific IP address or subnet')),
                        Text::make(__('Rate Limit: Limits connections to prevent brute-force attacks (6 connections in 30 seconds)')),
                        Text::make(__('Default Policy: Controls what happens to traffic that doesn\'t match any rule')),
                        Text::make(__('Important: Always ensure SSH (port 22) is allowed before enabling the firewall!')),
                    ]),
            ])->visible(fn () => $this->firewallInstalled),
        ];
    }

    protected function fail2banTabContent(): array
    {
        return [
            // Not installed state
            Section::make()
                ->schema([
                    Text::make(__('Fail2ban is not installed.')),
                    FormActions::make([
                        FormAction::make('installFail2ban')
                            ->label(__('Install Fail2ban'))
                            ->action('installFail2ban'),
                    ])->alignment(Alignment::Center),
                ])
                ->visible(fn () => ! $this->fail2banInstalled),
            // Installed state
            Group::make([
                Section::make(__('Fail2ban Status'))
                    ->icon('heroicon-o-lock-closed')
                    ->headerActions([
                        FormAction::make('fail2banStatus')
                            ->label(fn () => $this->fail2banRunning ? __('Running') : __('Stopped'))
                            ->color(fn () => $this->fail2banRunning ? 'success' : 'danger')
                            ->badge(),
                        FormAction::make('toggleFail2ban')
                            ->label(fn () => $this->fail2banRunning ? __('Stop') : __('Start'))
                            ->color(fn () => $this->fail2banRunning ? 'danger' : 'success')
                            ->size('sm')
                            ->action(fn () => $this->fail2banRunning ? $this->stopFail2ban() : $this->startFail2ban()),
                    ])
                    ->schema([
                        Grid::make(['default' => 1, 'md' => 3])
                            ->schema([
                                TextInput::make('maxRetry')
                                    ->label(__('Max Retry'))
                                    ->numeric()
                                    ->minValue(1)
                                    ->maxValue(20),
                                TextInput::make('banTime')
                                    ->label(__('Ban Time (seconds)'))
                                    ->numeric()
                                    ->minValue(60),
                                TextInput::make('findTime')
                                    ->label(__('Find Time (seconds)'))
                                    ->numeric()
                                    ->minValue(60),
                            ]),
                        FormActions::make([
                            FormAction::make('saveFail2banSettings')
                                ->label(__('Save Settings'))
                                ->action('saveFail2banSettings'),
                        ]),
                    ]),
                Section::make(__('Protection Modules'))
                    ->icon('heroicon-o-shield-exclamation')
                    ->description(__('Enable or disable protection modules for different services.'))
                    ->schema([
                        EmbeddedTable::make(JailsTable::class, ['jails' => $this->availableJails]),
                    ]),
                Section::make(__('Banned IPs').' ('.($this->totalBanned ?? __('N/A')).')')
                    ->icon('heroicon-o-no-symbol')
                    ->schema([
                        EmbeddedTable::make(BannedIpsTable::class, ['jails' => $this->jails]),
                    ])
                    ->visible(fn () => ($this->totalBanned ?? 0) > 0),
                Section::make(__('Fail2ban Logs'))
                    ->icon('heroicon-o-document-text')
                    ->schema([
                        EmbeddedTable::make(Fail2banLogsTable::class, ['logs' => $this->fail2banLogs]),
                    ])
                    ->collapsible(),
            ])->visible(fn () => $this->fail2banInstalled),
        ];
    }

    protected function antivirusTabContent(): array
    {
        return [
            // Warning for non-installed
            Section::make(__('Memory Requirements'))
                ->icon('heroicon-o-exclamation-triangle')
                ->iconColor('warning')
                ->description(__('ClamAV requires significant memory (~500MB+). Only install if your server has at least 2GB RAM available.'))
                ->visible(fn () => ! $this->clamavInstalled),
            // Not installed state
            Section::make()
                ->schema([
                    Text::make(__('ClamAV Antivirus is not installed.')),
                    FormActions::make([
                        FormAction::make('installClamav')
                            ->label(__('Install ClamAV'))
                            ->action('installClamav')
                            ->requiresConfirmation()
                            ->modalDescription(__('ClamAV uses significant memory. Are you sure you want to install it?')),
                    ])->alignment(Alignment::Center),
                ])
                ->visible(fn () => ! $this->clamavInstalled),
            // Installed state
            Group::make([
                Section::make(__('Resource Warning'))
                    ->icon('heroicon-o-exclamation-triangle')
                    ->iconColor('warning')
                    ->description(__('ClamAV uses significant memory (~500MB+) and CPU resources. Running the daemon or real-time protection on low-resource servers may impact performance. Consider using on-demand scanning instead.')),
                Section::make(__('ClamAV Status'))
                    ->icon('heroicon-o-shield-check')
                    ->headerActions([
                        FormAction::make('daemonStatus')
                            ->label(fn () => __('Daemon').' '.($this->clamavRunning ? __('Running') : __('Stopped')))
                            ->color(fn () => $this->clamavRunning ? 'success' : 'gray')
                            ->badge(),
                        FormAction::make('toggleClamav')
                            ->label(fn () => $this->clamavRunning ? __('Stop') : __('Start'))
                            ->color(fn () => $this->clamavRunning ? 'danger' : 'success')
                            ->size('sm')
                            ->action(fn () => $this->clamavRunning ? $this->stopClamav() : $this->startClamav())
                            ->requiresConfirmation(fn () => ! $this->clamavRunning)
                            ->modalDescription(__('Starting ClamAV daemon uses ~500MB RAM. Continue?')),
                        FormAction::make('updateSignatures')
                            ->label(__('Update Signatures'))
                            ->color('gray')
                            ->size('sm')
                            ->action('updateSignatures'),
                    ])
                    ->schema([
                        Grid::make(['default' => 1, 'md' => 3])
                            ->schema([
                                Section::make($this->clamavVersion ?: __('Unknown'))
                                    ->description(__('Version'))
                                    ->icon('heroicon-o-code-bracket')
                                    ->iconColor('gray'),
                                Section::make(number_format($this->signatureCount))
                                    ->description(__('Signatures'))
                                    ->icon('heroicon-o-document-text')
                                    ->iconColor('gray'),
                                Section::make($this->lastUpdate ?: __('Unknown'))
                                    ->description(__('Last Update'))
                                    ->icon('heroicon-o-clock')
                                    ->iconColor('gray'),
                            ]),
                        Grid::make(['default' => 1, 'md' => 2])
                            ->schema([
                                Section::make(__('Real-time Protection'))
                                    ->description(__('Monitors /home for new PHP, HTML, JS files'))
                                    ->icon($this->realtimeRunning ? 'heroicon-o-shield-check' : 'heroicon-o-shield-exclamation')
                                    ->iconColor($this->realtimeRunning ? 'success' : 'gray')
                                    ->schema([
                                        FormActions::make([
                                            FormAction::make('toggleRealtime')
                                                ->label(fn () => $this->realtimeRunning ? __('Disable') : __('Enable'))
                                                ->color(fn () => $this->realtimeRunning ? 'danger' : 'success')
                                                ->size('sm')
                                                ->action('toggleRealtime'),
                                        ]),
                                    ]),
                                Section::make(__('Database Mode'))
                                    ->description(fn () => $this->clamavLightMode
                                        ? __('Web hosting only: PHP, email, scripts (~50K sigs)')
                                        : __('Full database: all malware signatures'))
                                    ->icon($this->clamavLightMode ? 'heroicon-o-bolt' : 'heroicon-o-circle-stack')
                                    ->iconColor($this->clamavLightMode ? 'warning' : 'gray')
                                    ->schema([
                                        FormActions::make([
                                            FormAction::make('toggleLightMode')
                                                ->label(fn () => $this->clamavLightMode ? __('Full') : __('Light'))
                                                ->color(fn () => $this->clamavLightMode ? 'warning' : 'gray')
                                                ->size('sm')
                                                ->action('toggleLightMode')
                                                ->requiresConfirmation()
                                                ->modalDescription(fn () => $this->clamavLightMode
                                                    ? __('Switch to full database? This will download ~400MB of signatures.')
                                                    : __('Switch to lightweight mode? This reduces signatures to web hosting essentials only.')),
                                        ]),
                                    ]),
                            ]),
                    ]),
                Section::make(__('On-Demand Scanner'))
                    ->icon('heroicon-o-magnifying-glass')
                    ->description(__('Manually scan user directories or the entire server for malware and threats.'))
                    ->schema([
                        Grid::make(['default' => 1, 'md' => 2])
                            ->schema([
                                Section::make(__('Scan User Directory'))
                                    ->description(__('Scan a specific user\'s home directory for malware.'))
                                    ->icon('heroicon-o-user')
                                    ->iconColor('gray')
                                    ->schema([
                                        Select::make('selectedClamUser')
                                            ->label(__('Select User'))
                                            ->options(fn () => $this->getClamScanUsers())
                                            ->placeholder(__('Select a user to scan'))
                                            ->searchable()
                                            ->live(),
                                        FormActions::make([
                                            FormAction::make('runClamScanUser')
                                                ->label(fn () => $this->isScanning && $this->currentScan === 'clamav' ? __('Scanning...') : __('Scan User'))
                                                ->icon('heroicon-o-play')
                                                ->action('runClamScanUser')
                                                ->disabled(fn () => $this->isScanning || ! $this->selectedClamUser),
                                        ]),
                                    ]),
                                Section::make(__('Server-Wide Scan'))
                                    ->description(__('Scan all user directories (/home). This may take a long time.'))
                                    ->icon('heroicon-o-server')
                                    ->iconColor('warning')
                                    ->schema([
                                        Text::make(__('Server-wide scans can take 30+ minutes depending on data size.')),
                                        FormActions::make([
                                            FormAction::make('runClamScanServer')
                                                ->label(fn () => $this->isScanning && $this->currentScan === 'clamav' ? __('Scanning...') : __('Scan All Users'))
                                                ->icon('heroicon-o-server')
                                                ->color('warning')
                                                ->action('runClamScanServer')
                                                ->disabled(fn () => $this->isScanning)
                                                ->requiresConfirmation()
                                                ->modalDescription(__('This will scan all user directories and may take a long time. Continue?')),
                                        ]),
                                    ]),
                            ]),
                        Text::make($this->lastClamScan ? __('Last scan:').' '.$this->lastClamScan : '')
                            ->visible(fn () => (bool) $this->lastClamScan),
                    ]),
                Section::make(__('Scan Output'))
                    ->icon('heroicon-o-command-line')
                    ->collapsible()
                    ->schema(fn () => $this->buildClamScanOutputSchema())
                    ->visible(fn () => $this->isScanning && $this->currentScan === 'clamav' || ! empty($this->clamScanResults['raw_output'] ?? '')),
                Section::make(__('Scan Results'))
                    ->icon('heroicon-o-document-chart-bar')
                    ->collapsible()
                    ->schema(fn () => $this->buildClamavScanResultsSchema())
                    ->visible(fn () => ! empty($this->clamScanResults)),
                Section::make(__('Quarantined Files').' ('.count($this->quarantinedFiles).')')
                    ->icon('heroicon-o-archive-box')
                    ->schema([
                        EmbeddedTable::make(QuarantinedFilesTable::class, ['files' => $this->quarantinedFiles]),
                    ])
                    ->visible(fn () => count($this->quarantinedFiles) > 0),
                Section::make(__('Recent Threats'))
                    ->icon('heroicon-o-exclamation-triangle')
                    ->schema([
                        EmbeddedTable::make(ThreatsTable::class, ['threats' => $this->recentThreats]),
                    ])
                    ->visible(fn () => count($this->recentThreats) > 0),
            ])->visible(fn () => $this->clamavInstalled),
        ];
    }

    protected function sshTabContent(): array
    {
        return [
            // Current Configuration - 3 widgets on top
            Grid::make(['default' => 1, 'sm' => 3])
                ->schema([
                    Section::make($this->sshPasswordAuth ? __('Enabled') : __('Disabled'))
                        ->description(__('Password Auth'))
                        ->icon('heroicon-o-key')
                        ->iconColor($this->sshPasswordAuth ? 'warning' : 'success'),
                    Section::make($this->sshPubkeyAuth ? __('Enabled') : __('Disabled'))
                        ->description(__('Public Key Auth'))
                        ->icon('heroicon-o-finger-print')
                        ->iconColor($this->sshPubkeyAuth ? 'success' : 'danger'),
                    Section::make((string) $this->sshPort)
                        ->description(__('SSH Port'))
                        ->icon('heroicon-o-server')
                        ->iconColor($this->sshPort != 22 ? 'success' : 'gray'),
                ]),
            Section::make(__('Important Notice'))
                ->icon('heroicon-o-exclamation-triangle')
                ->iconColor('warning')
                ->description(__('Changing SSH settings can lock you out of the server. Ensure you have console access or an active SSH session before disabling password authentication.')),
            Section::make(__('SSH Authentication Settings'))
                ->icon('heroicon-o-command-line')
                ->schema([
                    Toggle::make('sshPasswordAuth')
                        ->label(__('Password Authentication'))
                        ->helperText(__('Allow users to log in using passwords. Disable for key-only access.')),
                    Toggle::make('sshPubkeyAuth')
                        ->label(__('Public Key Authentication'))
                        ->helperText(__('Allow users to log in using SSH keys. Recommended for security.')),
                    TextInput::make('sshPort')
                        ->label(__('SSH Port'))
                        ->numeric()
                        ->minValue(1)
                        ->maxValue(65535)
                        ->helperText(__('Default is 22. Changing port can help reduce automated attacks.'))
                        ->columnSpan(1),
                    FormActions::make([
                        FormAction::make('saveSshSettings')
                            ->label(__('Save SSH Settings'))
                            ->action('saveSshSettings')
                            ->requiresConfirmation()
                            ->modalDescription(__('Are you sure? This will restart the SSH service immediately.')),
                    ]),
                ]),
            Section::make(__('Security Recommendations'))
                ->icon('heroicon-o-light-bulb')
                ->schema(fn () => $this->buildSshRecommendationsSchema()),
        ];
    }

    protected function scannerTabContent(): array
    {
        return [
            Grid::make(['default' => 1, 'md' => 3])
                ->schema([
                    // Lynis
                    Section::make(__('Lynis'))
                        ->icon('heroicon-o-shield-check')
                        ->description(__('System security auditing tool. Checks configurations, permissions, and hardening settings.'))
                        ->headerActions([
                            FormAction::make('lynisStatus')
                                ->label(fn () => $this->lynisInstalled ? __('Installed') : __('Not Installed'))
                                ->color(fn () => $this->lynisInstalled ? 'success' : 'danger')
                                ->badge(),
                        ])
                        ->schema([
                            Group::make([
                                Text::make($this->lynisVersion)
                                    ->visible(fn () => $this->lynisInstalled && $this->lynisVersion),
                                Text::make($this->lastLynisScan ? __('Last:').' '.$this->lastLynisScan : '')
                                    ->visible(fn () => $this->lynisInstalled && $this->lastLynisScan),
                            ])->visible(fn () => $this->lynisInstalled),

                            FormActions::make([
                                FormAction::make('runLynisScan')
                                    ->label(fn () => $this->isScanning && $this->currentScan === 'lynis' ? __('Scanning...') : __('Run System Audit'))
                                    ->icon('heroicon-o-play')
                                    ->color('success')
                                    ->action('runLynisScan')
                                    ->disabled(fn () => $this->isScanning),
                            ])->visible(fn () => $this->lynisInstalled),

                            FormActions::make([
                                FormAction::make('installLynis')
                                    ->label(__('Install Lynis'))
                                    ->icon('heroicon-o-arrow-down-tray')
                                    ->action('installLynis'),
                            ])->visible(fn () => ! $this->lynisInstalled),
                        ]),

                    // WPScan
                    Section::make(__('WPScan'))
                        ->icon('heroicon-o-globe-alt')
                        ->description(__('WordPress vulnerability scanner. Checks for vulnerable plugins, themes, and core issues.'))
                        ->headerActions([
                            FormAction::make('wpscanStatus')
                                ->label(fn () => $this->wpscanInstalled ? __('Installed') : __('Not Installed'))
                                ->color(fn () => $this->wpscanInstalled ? 'success' : 'danger')
                                ->badge(),
                        ])
                        ->schema([
                            Group::make([
                                Text::make($this->wpscanVersion)
                                    ->visible(fn () => $this->wpscanInstalled && $this->wpscanVersion),
                                Text::make($this->lastWpscanScan ? __('Last:').' '.$this->lastWpscanScan : '')
                                    ->visible(fn () => $this->wpscanInstalled && $this->lastWpscanScan),

                                Select::make('selectedWpSiteId')
                                    ->label(__('WordPress Site'))
                                    ->options(fn () => $this->getLocalWordPressSites())
                                    ->placeholder(__('Select a WordPress site'))
                                    ->searchable()
                                    ->live()
                                    ->visible(fn () => count($this->getLocalWordPressSites()) > 0),

                                Text::make(__('No WordPress sites found'))
                                    ->visible(fn () => count($this->getLocalWordPressSites()) === 0),
                            ])->visible(fn () => $this->wpscanInstalled),

                            FormActions::make([
                                FormAction::make('runWpscanOnSite')
                                    ->label(fn () => $this->isScanning && $this->currentScan === 'wpscan' ? __('Scanning...') : __('Scan WordPress Site'))
                                    ->icon('heroicon-o-play')
                                    ->color('info')
                                    ->action('runWpscanOnSite')
                                    ->disabled(fn () => $this->isScanning || ! $this->selectedWpSiteId),
                            ])->visible(fn () => $this->wpscanInstalled && count($this->getLocalWordPressSites()) > 0),

                            FormActions::make([
                                FormAction::make('installWpscan')
                                    ->label(__('Install WPScan'))
                                    ->icon('heroicon-o-arrow-down-tray')
                                    ->action('installWpscan'),
                            ])->visible(fn () => ! $this->wpscanInstalled),
                        ]),

                    // Nikto
                    Section::make(__('Nikto'))
                        ->icon('heroicon-o-server')
                        ->description(__('Web server scanner. Finds server misconfigurations and known vulnerabilities on localhost.'))
                        ->headerActions([
                            FormAction::make('niktoStatus')
                                ->label(fn () => $this->niktoInstalled ? __('Installed') : __('Not Installed'))
                                ->color(fn () => $this->niktoInstalled ? 'success' : 'danger')
                                ->badge(),
                        ])
                        ->schema([
                            Group::make([
                                Text::make($this->niktoVersion)
                                    ->visible(fn () => $this->niktoInstalled && $this->niktoVersion),
                                Text::make($this->lastNiktoScan ? __('Last:').' '.$this->lastNiktoScan : '')
                                    ->visible(fn () => $this->niktoInstalled && $this->lastNiktoScan),
                            ])->visible(fn () => $this->niktoInstalled),

                            FormActions::make([
                                FormAction::make('runNiktoScan')
                                    ->label(fn () => $this->isScanning && $this->currentScan === 'nikto' ? __('Scanning...') : __('Scan Local Server'))
                                    ->icon('heroicon-o-play')
                                    ->color('warning')
                                    ->action('runNiktoScan')
                                    ->disabled(fn () => $this->isScanning),
                            ])->visible(fn () => $this->niktoInstalled),

                            FormActions::make([
                                FormAction::make('installNikto')
                                    ->label(__('Install Nikto'))
                                    ->icon('heroicon-o-arrow-down-tray')
                                    ->action('installNikto'),
                            ])->visible(fn () => ! $this->niktoInstalled),
                        ]),
                ]),

            // Lynis Results
            Section::make(__('Lynis System Audit Results'))
                ->icon('heroicon-o-document-chart-bar')
                ->schema([
                    Grid::make(['default' => 1, 'md' => 3])
                        ->schema([
                            Section::make((string) ($this->lynisResults['hardening_index'] ?? 0))
                                ->description(__('Hardening Index'))
                                ->icon('heroicon-o-shield-check')
                                ->iconColor(fn () => ($this->lynisResults['hardening_index'] ?? 0) >= 70 ? 'success' : (($this->lynisResults['hardening_index'] ?? 0) >= 50 ? 'warning' : 'danger')),
                            Section::make((string) count($this->lynisResults['warnings'] ?? []))
                                ->description(__('Warnings'))
                                ->icon('heroicon-o-exclamation-triangle')
                                ->iconColor('warning'),
                            Section::make((string) count($this->lynisResults['suggestions'] ?? []))
                                ->description(__('Suggestions'))
                                ->icon('heroicon-o-light-bulb')
                                ->iconColor('primary'),
                        ]),
                    Section::make(__('Warnings'))
                        ->icon('heroicon-o-exclamation-triangle')
                        ->iconColor('warning')
                        ->collapsible()
                        ->schema([
                            EmbeddedTable::make(LynisResultsTable::class, ['results' => $this->lynisResults, 'type' => 'warnings']),
                        ])
                        ->visible(fn () => ! empty($this->lynisResults['warnings'] ?? [])),
                    Section::make(__('Suggestions'))
                        ->icon('heroicon-o-light-bulb')
                        ->iconColor('info')
                        ->collapsible()
                        ->schema([
                            EmbeddedTable::make(LynisResultsTable::class, ['results' => $this->lynisResults, 'type' => 'suggestions']),
                        ])
                        ->visible(fn () => ! empty($this->lynisResults['suggestions'] ?? [])),
                ])
                ->visible(fn () => ! empty($this->lynisResults)),

            // WPScan Results
            Section::make(__('WPScan Results'))
                ->icon('heroicon-o-globe-alt')
                ->schema([
                    Section::make('WordPress '.($this->wpscanResults['version']['number'] ?? __('Unknown')))
                        ->icon('heroicon-o-code-bracket')
                        ->iconColor('info')
                        ->visible(fn () => isset($this->wpscanResults['version']['number'])),
                    EmbeddedTable::make(WpscanResultsTable::class, ['results' => $this->wpscanResults]),
                ])
                ->visible(fn () => ! empty($this->wpscanResults) && ! isset($this->wpscanResults['error'])),

            // Nikto Results
            Section::make(__('Nikto Scan Results'))
                ->icon('heroicon-o-server')
                ->schema([
                    Section::make(__('Vulnerabilities'))
                        ->icon('heroicon-o-exclamation-triangle')
                        ->iconColor('danger')
                        ->collapsible()
                        ->schema([
                            EmbeddedTable::make(NiktoResultsTable::class, ['results' => $this->niktoResults, 'type' => 'vulnerabilities']),
                        ])
                        ->visible(fn () => ! empty($this->niktoResults['vulnerabilities'] ?? [])),
                    Section::make(__('Information'))
                        ->icon('heroicon-o-information-circle')
                        ->iconColor('info')
                        ->collapsible()
                        ->schema([
                            EmbeddedTable::make(NiktoResultsTable::class, ['results' => $this->niktoResults, 'type' => 'info']),
                        ])
                        ->visible(fn () => ! empty($this->niktoResults['info'] ?? [])),
                ])
                ->visible(fn () => ! empty($this->niktoResults)),

            // Scan Output
            Section::make(__('Scan Output'))
                ->icon('heroicon-o-command-line')
                ->schema(fn () => $this->buildScanOutputSchema())
                ->visible(fn () => (bool) $this->scanOutput),
        ];
    }

    protected function getHeaderActions(): array
    {
        return [
        ];
    }

    // Load methods
    protected function loadFirewallStatus(): void
    {
        try {
            $result = $this->getAgent()->send('ufw.status');
            $this->firewallInstalled = true;
            $this->firewallEnabled = $result['active'] ?? false;
            $this->defaultIncoming = $result['default_incoming'] ?? 'deny';
            $this->defaultOutgoing = $result['default_outgoing'] ?? 'allow';
            $this->firewallStatusText = $result['status_text'] ?? '';

            $rulesResult = $this->getAgent()->send('ufw.list_rules');
            $this->firewallRules = $rulesResult['rules'] ?? [];
        } catch (Exception $e) {
            $this->firewallInstalled = false;
        }
    }

    protected function loadFail2banStatusLight(): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.status_light');
            $this->fail2banInstalled = $result['installed'] ?? false;
            $this->fail2banRunning = $result['running'] ?? false;
            $this->fail2banVersion = $result['version'] ?? 'Unknown';
            $this->jails = [];
            $this->availableJails = [];
            $this->totalBanned = null;
            $this->fail2banLogs = [];
        } catch (Exception $e) {
            $this->fail2banInstalled = false;
            $this->fail2banRunning = false;
            $this->fail2banVersion = '';
            $this->jails = [];
            $this->availableJails = [];
            $this->totalBanned = null;
            $this->fail2banLogs = [];
        }
    }

    protected function loadFail2banStatus(): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.status');
            $this->fail2banInstalled = $result['installed'] ?? false;

            if ($this->fail2banInstalled) {
                $this->fail2banRunning = $result['running'] ?? false;
                $this->fail2banVersion = $result['version'] ?? 'Unknown';
                $this->jails = $result['jails'] ?? [];
                $this->totalBanned = $result['total_banned'] ?? 0;
                $this->maxRetry = $result['max_retry'] ?? 5;
                $this->banTime = $result['ban_time'] ?? 600;
                $this->findTime = $result['find_time'] ?? 600;

                $jailsResult = $this->getAgent()->send('fail2ban.list_jails');
                $this->availableJails = $jailsResult['jails'] ?? [];

                $logsResult = $this->getAgent()->send('fail2ban.logs');
                $this->fail2banLogs = $logsResult['logs'] ?? [];
            } else {
                $this->fail2banRunning = false;
                $this->fail2banVersion = '';
                $this->jails = [];
                $this->availableJails = [];
                $this->totalBanned = null;
                $this->fail2banLogs = [];
            }
        } catch (Exception $e) {
            $this->fail2banInstalled = false;
            $this->fail2banRunning = false;
            $this->fail2banVersion = '';
            $this->jails = [];
            $this->availableJails = [];
            $this->totalBanned = null;
            $this->fail2banLogs = [];
        }
    }

    protected function loadClamavStatusLight(): void
    {
        try {
            $result = $this->getAgent()->send('clamav.status_light');
            $this->clamavInstalled = $result['installed'] ?? false;
            $this->clamavRunning = $result['running'] ?? false;
            $this->clamavVersion = $result['version'] ?? 'Unknown';
            $this->realtimeEnabled = $result['realtime_enabled'] ?? false;
            $this->realtimeRunning = $result['realtime_running'] ?? false;
            $this->clamavLightMode = $result['light_mode'] ?? false;

            $this->signatureCount = 0;
            $this->lastUpdate = '';
            $this->recentThreats = [];
            $this->quarantinedFiles = [];
            $this->signatureDatabases = [];
        } catch (Exception $e) {
            $this->clamavInstalled = false;
            $this->clamavRunning = false;
            $this->clamavVersion = '';
            $this->realtimeEnabled = false;
            $this->realtimeRunning = false;
            $this->clamavLightMode = false;

            $this->signatureCount = 0;
            $this->lastUpdate = '';
            $this->recentThreats = [];
            $this->quarantinedFiles = [];
            $this->signatureDatabases = [];
        }
    }

    protected function loadClamavStatus(): void
    {
        try {
            $result = $this->getAgent()->send('clamav.status');
            $this->clamavInstalled = $result['installed'] ?? false;

            if ($this->clamavInstalled) {
                $this->clamavRunning = $result['running'] ?? false;
                $this->clamavVersion = $result['version'] ?? 'Unknown';
                $this->signatureCount = $result['signature_count'] ?? 0;
                $this->lastUpdate = $result['last_update'] ?? '';
                $this->recentThreats = $result['recent_threats'] ?? [];
                $this->quarantinedFiles = $result['quarantined_files'] ?? [];
                $this->realtimeEnabled = $result['realtime_enabled'] ?? false;
                $this->realtimeRunning = $result['realtime_running'] ?? false;
                $this->clamavLightMode = $result['light_mode'] ?? false;
                $this->signatureDatabases = $result['signature_databases'] ?? [];
            } else {
                $this->clamavRunning = false;
                $this->clamavVersion = '';
                $this->signatureCount = 0;
                $this->lastUpdate = '';
                $this->recentThreats = [];
                $this->quarantinedFiles = [];
                $this->realtimeEnabled = false;
                $this->realtimeRunning = false;
                $this->clamavLightMode = false;
                $this->signatureDatabases = [];
            }
        } catch (Exception $e) {
            $this->clamavInstalled = false;
            $this->clamavRunning = false;
            $this->clamavVersion = '';
            $this->signatureCount = 0;
            $this->lastUpdate = '';
            $this->recentThreats = [];
            $this->quarantinedFiles = [];
            $this->realtimeEnabled = false;
            $this->realtimeRunning = false;
            $this->clamavLightMode = false;
            $this->signatureDatabases = [];
        }
    }

    protected function loadSshSettings(): void
    {
        try {
            $result = $this->getAgent()->send('ssh.get_settings');
            if ($result['success'] ?? false) {
                $this->sshPasswordAuth = $result['password_auth'] ?? false;
                $this->sshPubkeyAuth = $result['pubkey_auth'] ?? true;
                $this->sshPort = $result['port'] ?? 22;
            }
        } catch (Exception $e) {
            // Use defaults
        }
    }

    public function saveSshSettings(): void
    {
        try {
            if (! $this->sshPasswordAuth && ! $this->sshPubkeyAuth) {
                Notification::make()
                    ->title(__('Invalid Configuration'))
                    ->body(__('At least one authentication method must be enabled.'))
                    ->danger()
                    ->send();

                return;
            }

            $result = $this->getAgent()->send('ssh.save_settings', [
                'password_auth' => $this->sshPasswordAuth,
                'pubkey_auth' => $this->sshPubkeyAuth,
                'port' => $this->sshPort,
            ]);

            if ($result['success'] ?? false) {
                Notification::make()
                    ->title(__('SSH settings saved'))
                    ->body(__('Changes will take effect immediately. Make sure you have key access if disabling passwords.'))
                    ->success()
                    ->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to save settings'));
            }
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Failed to save SSH settings'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
        $this->loadSshSettings();
    }

    // Firewall actions
    public function toggleFirewall(): void
    {
        try {
            $action = $this->firewallEnabled ? 'ufw.disable' : 'ufw.enable';
            $result = $this->getAgent()->send($action);

            if ($result['success'] ?? false) {
                $this->firewallEnabled = ! $this->firewallEnabled;
                $auditAction = $this->firewallEnabled ? 'enabled' : 'disabled';
                AuditLog::logFirewallAction($auditAction);
                Notification::make()
                    ->title($this->firewallEnabled ? __('Firewall enabled') : __('Firewall disabled'))
                    ->success()
                    ->send();
            } else {
                throw new Exception($result['message'] ?? __('Unknown error'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
        }

        $this->loadFirewallStatus();
    }

    public function installFirewall(): void
    {
        Notification::make()->title(__('Installing firewall...'))->info()->send();
        try {
            $this->getAgent()->send('ufw.enable');
            $this->getAgent()->send('ufw.allow_service', ['service' => 'ssh']);
            $this->getAgent()->send('ufw.allow_service', ['service' => 'http']);
            $this->getAgent()->send('ufw.allow_service', ['service' => 'https']);
            AuditLog::logFirewallAction('installed', 'default rules configured');
            Notification::make()->title(__('Firewall configured with default rules'))->success()->send();
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to configure firewall'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFirewallStatus();
    }

    public function deleteRule(int $ruleNumber): void
    {
        $this->ruleToDelete = $ruleNumber;
        $this->mountAction('deleteRuleAction');
    }

    public function deleteRuleAction(): Action
    {
        return Action::make('deleteRuleAction')
            ->requiresConfirmation()
            ->modalHeading(__('Delete Firewall Rule'))
            ->modalDescription(fn () => __('Are you sure you want to delete rule #:number?', ['number' => $this->ruleToDelete]))
            ->modalSubmitActionLabel(__('Delete'))
            ->color('danger')
            ->action(function (): void {
                try {
                    $result = $this->getAgent()->send('ufw.delete_rule', ['rule_number' => $this->ruleToDelete]);
                    if ($result['success'] ?? false) {
                        AuditLog::logFirewallAction('deleted', "rule #{$this->ruleToDelete}");
                        Notification::make()->title(__('Rule deleted'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    public function setDefaultPolicy(string $direction): void
    {
        $this->mountAction('setDefaultPolicyAction', ['direction' => $direction]);
    }

    public function setDefaultPolicyAction(): Action
    {
        return Action::make('setDefaultPolicyAction')
            ->modalHeading(__('Set Default Policy'))
            ->form([
                Select::make('policy')
                    ->label(__('Policy'))
                    ->options([
                        'allow' => __('Allow'),
                        'deny' => __('Deny'),
                        'reject' => __('Reject'),
                    ])
                    ->required(),
            ])
            ->action(function (array $data, array $arguments): void {
                try {
                    $result = $this->getAgent()->send('ufw.set_default', [
                        'direction' => $arguments['direction'] ?? 'incoming',
                        'policy' => $data['policy'],
                    ]);
                    if ($result['success'] ?? false) {
                        Notification::make()->title(__('Default policy updated'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    public function reloadFirewall(): void
    {
        try {
            $result = $this->getAgent()->send('ufw.reload');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Firewall reloaded'))->success()->send();
                $this->loadFirewallStatus();
            } else {
                throw new Exception($result['message'] ?? __('Unknown error'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
        }
    }

    public function resetFirewall(): void
    {
        $this->mountAction('resetFirewallAction');
    }

    public function resetFirewallAction(): Action
    {
        return Action::make('resetFirewallAction')
            ->requiresConfirmation()
            ->modalHeading(__('Reset Firewall'))
            ->modalDescription(__('This will delete ALL firewall rules and disable the firewall. Are you sure?'))
            ->modalSubmitActionLabel(__('Reset Everything'))
            ->color('danger')
            ->action(function (): void {
                try {
                    $result = $this->getAgent()->send('ufw.reset');
                    if ($result['success'] ?? false) {
                        AuditLog::logFirewallAction('reset', 'all rules deleted');
                        Notification::make()->title(__('Firewall reset'))->body(__('All rules have been deleted.'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    protected function allowPortAction(): Action
    {
        return Action::make('allowPort')
            ->label(__('Allow Port'))
            ->icon('heroicon-o-plus-circle')
            ->color('success')
            ->form([
                TextInput::make('port')
                    ->label(__('Port'))
                    ->placeholder(__('e.g., 80, 443, 8000:8100'))
                    ->required()
                    ->helperText(__('Single port or range (e.g., 8000:8100)')),
                Select::make('protocol')
                    ->label(__('Protocol'))
                    ->options([
                        '' => __('Both (TCP & UDP)'),
                        'tcp' => __('TCP only'),
                        'udp' => __('UDP only'),
                    ])
                    ->default(''),
                TextInput::make('comment')
                    ->label(__('Comment (optional)'))
                    ->placeholder(__('e.g., Web server')),
            ])
            ->action(function (array $data): void {
                try {
                    $result = $this->getAgent()->send('ufw.allow_port', $data);
                    if ($result['success'] ?? false) {
                        $rule = "allow port {$data['port']}".($data['protocol'] ? "/{$data['protocol']}" : '');
                        AuditLog::logFirewallAction('added', $rule, $data);
                        Notification::make()->title(__('Port allowed'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['error'] ?? $result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    protected function denyPortAction(): Action
    {
        return Action::make('denyPort')
            ->label(__('Block Port'))
            ->icon('heroicon-o-x-circle')
            ->color('danger')
            ->form([
                TextInput::make('port')
                    ->label(__('Port'))
                    ->placeholder(__('e.g., 3306'))
                    ->required(),
                Select::make('protocol')
                    ->label(__('Protocol'))
                    ->options([
                        '' => __('Both (TCP & UDP)'),
                        'tcp' => __('TCP only'),
                        'udp' => __('UDP only'),
                    ])
                    ->default(''),
                TextInput::make('comment')
                    ->label(__('Comment (optional)')),
            ])
            ->action(function (array $data): void {
                try {
                    $result = $this->getAgent()->send('ufw.deny_port', $data);
                    if ($result['success'] ?? false) {
                        $rule = "deny port {$data['port']}".($data['protocol'] ? "/{$data['protocol']}" : '');
                        AuditLog::logFirewallAction('added', $rule, $data);
                        Notification::make()->title(__('Port blocked'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['error'] ?? $result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    protected function allowIpAction(): Action
    {
        return Action::make('allowIp')
            ->label(__('Allow IP'))
            ->icon('heroicon-o-check-circle')
            ->color('success')
            ->form([
                TextInput::make('ip')
                    ->label(__('IP Address'))
                    ->placeholder(__('e.g., 192.168.1.100 or 10.0.0.0/8'))
                    ->required()
                    ->helperText(__('Single IP or CIDR notation')),
                TextInput::make('port')
                    ->label(__('Port (optional)'))
                    ->placeholder(__('Leave empty to allow all ports')),
                Select::make('protocol')
                    ->label(__('Protocol'))
                    ->options([
                        '' => __('Any'),
                        'tcp' => __('TCP'),
                        'udp' => __('UDP'),
                    ])
                    ->default(''),
                TextInput::make('comment')
                    ->label(__('Comment (optional)')),
            ])
            ->action(function (array $data): void {
                try {
                    $result = $this->getAgent()->send('ufw.allow_ip', $data);
                    if ($result['success'] ?? false) {
                        $rule = "allow from {$data['ip']}".($data['port'] ? " to port {$data['port']}" : '');
                        AuditLog::logFirewallAction('added', $rule, $data);
                        Notification::make()->title(__('IP allowed'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['error'] ?? $result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    protected function denyIpAction(): Action
    {
        return Action::make('denyIp')
            ->label(__('Block IP'))
            ->icon('heroicon-o-no-symbol')
            ->color('danger')
            ->form([
                TextInput::make('ip')
                    ->label(__('IP Address'))
                    ->placeholder(__('e.g., 192.168.1.100 or 10.0.0.0/8'))
                    ->required(),
                TextInput::make('port')
                    ->label(__('Port (optional)'))
                    ->placeholder(__('Leave empty to block all ports')),
                Select::make('protocol')
                    ->label(__('Protocol'))
                    ->options([
                        '' => __('Any'),
                        'tcp' => __('TCP'),
                        'udp' => __('UDP'),
                    ])
                    ->default(''),
                TextInput::make('comment')
                    ->label(__('Comment (optional)')),
            ])
            ->action(function (array $data): void {
                try {
                    $result = $this->getAgent()->send('ufw.deny_ip', $data);
                    if ($result['success'] ?? false) {
                        $rule = "deny from {$data['ip']}".($data['port'] ? " to port {$data['port']}" : '');
                        AuditLog::logFirewallAction('added', $rule, $data);
                        Notification::make()->title(__('IP blocked'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['error'] ?? $result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    protected function allowServiceAction(): Action
    {
        return Action::make('allowService')
            ->label(__('Allow Service'))
            ->icon('heroicon-o-server')
            ->color('info')
            ->form([
                Select::make('service')
                    ->label(__('Service'))
                    ->options([
                        'ssh' => __('SSH (22)'),
                        'http' => __('HTTP (80)'),
                        'https' => __('HTTPS (443)'),
                        'ftp' => __('FTP (21)'),
                        'smtp' => __('SMTP (25)'),
                        'pop3' => __('POP3 (110)'),
                        'imap' => __('IMAP (143)'),
                        'dns' => __('DNS (53)'),
                        'mysql' => __('MySQL (3306)'),
                        'postgresql' => __('PostgreSQL (5432)'),
                    ])
                    ->required()
                    ->searchable(),
            ])
            ->action(function (array $data): void {
                try {
                    $result = $this->getAgent()->send('ufw.allow_service', $data);
                    if ($result['success'] ?? false) {
                        AuditLog::logFirewallAction('added', "allow service {$data['service']}", $data);
                        Notification::make()->title(__('Service allowed'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['error'] ?? $result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    protected function limitPortAction(): Action
    {
        return Action::make('limitPort')
            ->label(__('Rate Limit'))
            ->icon('heroicon-o-clock')
            ->color('warning')
            ->form([
                TextInput::make('port')
                    ->label(__('Port'))
                    ->placeholder(__('e.g., 22'))
                    ->required()
                    ->helperText(__('Limit connections (6 in 30 seconds)')),
                Select::make('protocol')
                    ->label(__('Protocol'))
                    ->options([
                        'tcp' => __('TCP'),
                        'udp' => __('UDP'),
                    ])
                    ->default('tcp'),
            ])
            ->action(function (array $data): void {
                try {
                    $result = $this->getAgent()->send('ufw.limit_port', $data);
                    if ($result['success'] ?? false) {
                        AuditLog::logFirewallAction('added', "limit port {$data['port']}/{$data['protocol']}", $data);
                        Notification::make()->title(__('Rate limit applied'))->success()->send();
                        $this->loadFirewallStatus();
                    } else {
                        throw new Exception($result['error'] ?? $result['message'] ?? __('Unknown error'));
                    }
                } catch (Exception $e) {
                    Notification::make()->title(__('Error'))->body($e->getMessage())->danger()->send();
                }
            });
    }

    public function getActionColor(string $action): string
    {
        return match (strtoupper($action)) {
            'ALLOW' => 'success',
            'DENY' => 'danger',
            'REJECT' => 'warning',
            'LIMIT' => 'warning',
            default => 'gray',
        };
    }

    // Firewall action mount helpers
    public function openAllowPort(): void
    {
        $this->mountAction('allowPort');
    }

    public function openDenyPort(): void
    {
        $this->mountAction('denyPort');
    }

    public function openAllowIp(): void
    {
        $this->mountAction('allowIp');
    }

    public function openDenyIp(): void
    {
        $this->mountAction('denyIp');
    }

    public function openAllowService(): void
    {
        $this->mountAction('allowService');
    }

    public function openLimitPort(): void
    {
        $this->mountAction('limitPort');
    }

    // Fail2ban actions
    public function installFail2ban(): void
    {
        Notification::make()->title(__('Installing Fail2ban...'))->info()->send();
        try {
            $result = $this->getAgent()->send('fail2ban.install');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Fail2ban installed'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Installation failed'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to install Fail2ban'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFail2banStatus();
    }

    public function startFail2ban(): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.start');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Fail2ban started'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to start'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to start Fail2ban'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFail2banStatus();
    }

    public function stopFail2ban(): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.stop');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Fail2ban stopped'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to stop'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to stop Fail2ban'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFail2banStatus();
    }

    public function saveFail2banSettings(): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.save_settings', [
                'max_retry' => $this->maxRetry,
                'ban_time' => $this->banTime,
                'find_time' => $this->findTime,
            ]);
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Settings saved'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to save'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to save settings'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFail2banStatus();
    }

    public function unbanIp(string $jail, string $ip): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.unban_ip', ['jail' => $jail, 'ip' => $ip]);
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Unbanned :ip', ['ip' => $ip]))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to unban'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to unban IP'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFail2banStatus();
    }

    public function enableJail(string $jail): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.enable_jail', ['jail' => $jail]);
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Jail :jail enabled', ['jail' => $jail]))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to enable jail'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to enable jail'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFail2banStatus();
    }

    public function disableJail(string $jail): void
    {
        try {
            $result = $this->getAgent()->send('fail2ban.disable_jail', ['jail' => $jail]);
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Jail :jail disabled', ['jail' => $jail]))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to disable jail'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to disable jail'))->body($e->getMessage())->danger()->send();
        }
        $this->loadFail2banStatus();
    }

    // ClamAV actions
    public function installClamav(): void
    {
        Notification::make()->title(__('Installing ClamAV...'))->body(__('This may take a few minutes.'))->info()->send();
        try {
            $result = $this->getAgent()->send('clamav.install');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('ClamAV installed'))->body(__('Daemon disabled by default to save memory.'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Installation failed'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to install ClamAV'))->body($e->getMessage())->danger()->send();
        }
        $this->loadClamavStatus();
    }

    public function updateSignatures(): void
    {
        try {
            $result = $this->getAgent()->send('clamav.update_signatures');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('Signatures updated'))->success()->send();
            } else {
                Notification::make()->title(__('Update may have issues'))->body($result['output'] ?? '')->warning()->send();
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to update signatures'))->body($e->getMessage())->danger()->send();
        }
        $this->loadClamavStatus();
    }

    public function startClamav(): void
    {
        try {
            $result = $this->getAgent()->send('clamav.start');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('ClamAV started'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to start'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to start ClamAV'))->body($e->getMessage())->danger()->send();
        }
        $this->loadClamavStatus();
    }

    public function stopClamav(): void
    {
        try {
            $result = $this->getAgent()->send('clamav.stop');
            if ($result['success'] ?? false) {
                Notification::make()->title(__('ClamAV stopped'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to stop'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to stop ClamAV'))->body($e->getMessage())->danger()->send();
        }
        $this->loadClamavStatus();
    }

    public function toggleRealtime(): void
    {
        try {
            if ($this->realtimeRunning) {
                $result = $this->getAgent()->send('clamav.realtime_disable');
                $message = __('Real-time protection disabled');
            } else {
                $result = $this->getAgent()->send('clamav.realtime_enable');
                $message = __('Real-time protection enabled');
            }
            if ($result['success'] ?? false) {
                Notification::make()->title($message)->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to toggle real-time protection'))->body($e->getMessage())->danger()->send();
        }
        $this->loadClamavStatus();
    }

    public function toggleLightMode(): void
    {
        try {
            $action = $this->clamavLightMode ? 'clamav.set_full_mode' : 'clamav.set_light_mode';
            $result = $this->getAgent()->send($action);

            if ($result['success'] ?? false) {
                $this->clamavLightMode = ! $this->clamavLightMode;
                $message = $this->clamavLightMode
                    ? __('Switched to lightweight mode - web hosting signatures only')
                    : __('Switched to full mode - all ClamAV signatures');
                Notification::make()
                    ->title($message)
                    ->body(__('Signature count: :count', ['count' => number_format($result['signature_count'] ?? 0)]))
                    ->success()
                    ->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to switch mode'));
            }
        } catch (Exception $e) {
            Notification::make()
                ->title(__('Failed to switch ClamAV mode'))
                ->body($e->getMessage())
                ->danger()
                ->send();
        }
        $this->loadClamavStatus();
    }

    public function deleteQuarantined(string $filename): void
    {
        try {
            $result = $this->getAgent()->send('clamav.delete_quarantined', ['filename' => $filename]);
            if ($result['success'] ?? false) {
                Notification::make()->title(__('File deleted'))->success()->send();
            } else {
                throw new Exception($result['error'] ?? __('Failed to delete'));
            }
        } catch (Exception $e) {
            Notification::make()->title(__('Failed to delete file'))->body($e->getMessage())->danger()->send();
        }
        $this->loadClamavStatus();
    }

    // Scanner methods
    protected function checkScannerToolStatus(): void
    {
        exec('which lynis 2>/dev/null', $output, $code);
        $this->lynisInstalled = $code === 0;
        if ($this->lynisInstalled) {
            exec('lynis --version 2>/dev/null | head -1', $versionOutput);
            $this->lynisVersion = trim($versionOutput[0] ?? 'Unknown');
        }

        exec('which wpscan 2>/dev/null', $output2, $code2);
        $this->wpscanInstalled = $code2 === 0;
        if ($this->wpscanInstalled) {
            exec("wpscan --version 2>/dev/null | grep -i 'version' | tail -1", $versionOutput2);
            $this->wpscanVersion = trim($versionOutput2[0] ?? 'Unknown');
        }

        exec('which nikto 2>/dev/null', $output3, $code3);
        $this->niktoInstalled = $code3 === 0;
        if ($this->niktoInstalled) {
            exec('nikto -Version 2>/dev/null | grep -i version | head -1', $versionOutput3);
            $this->niktoVersion = trim($versionOutput3[0] ?? 'Unknown');
        }
    }

    protected function loadLastScans(): void
    {
        $scanDir = storage_path('app/security-scans');

        if (file_exists("$scanDir/lynis-latest.json")) {
            $this->lastLynisScan = date('Y-m-d H:i:s', filemtime("$scanDir/lynis-latest.json"));
            $this->lynisResults = json_decode(file_get_contents("$scanDir/lynis-latest.json"), true) ?? [];
        }

        if (file_exists("$scanDir/wpscan-latest.json")) {
            $this->lastWpscanScan = date('Y-m-d H:i:s', filemtime("$scanDir/wpscan-latest.json"));
            $this->wpscanResults = json_decode(file_get_contents("$scanDir/wpscan-latest.json"), true) ?? [];
        }

        if (file_exists("$scanDir/nikto-latest.json")) {
            $this->lastNiktoScan = date('Y-m-d H:i:s', filemtime("$scanDir/nikto-latest.json"));
            $this->niktoResults = json_decode(file_get_contents("$scanDir/nikto-latest.json"), true) ?? [];
        }
    }

    public function installLynis(): void
    {
        Notification::make()->title(__('Installing Lynis...'))->info()->send();
        exec('apt-get update && apt-get install -y lynis 2>&1', $output, $code);

        if ($code === 0) {
            Notification::make()->title(__('Lynis installed successfully'))->success()->send();
        } else {
            Notification::make()->title(__('Installation failed'))->body(implode("\n", array_slice($output, -5)))->danger()->send();
        }
        $this->checkScannerToolStatus();
    }

    public function installWpscan(): void
    {
        Notification::make()->title(__('Installing WPScan...'))->body(__('This may take a few minutes.'))->info()->send();

        exec('which ruby 2>/dev/null', $rubyCheck, $rubyCode);
        if ($rubyCode !== 0) {
            exec('apt-get update && apt-get install -y ruby ruby-dev build-essential libcurl4-openssl-dev libxml2 libxml2-dev libxslt1-dev 2>&1', $output, $code);
        }

        exec('gem install wpscan 2>&1', $output, $code);

        if ($code === 0) {
            exec('wpscan --update 2>&1');
            Notification::make()->title(__('WPScan installed successfully'))->success()->send();
        } else {
            Notification::make()->title(__('Installation failed'))->body(implode("\n", array_slice($output, -5)))->danger()->send();
        }
        $this->checkScannerToolStatus();
    }

    public function installNikto(): void
    {
        Notification::make()->title(__('Installing Nikto...'))->info()->send();
        exec('apt-get update && apt-get install -y nikto 2>&1', $output, $code);

        if ($code === 0) {
            Notification::make()->title(__('Nikto installed successfully'))->success()->send();
        } else {
            Notification::make()->title(__('Installation failed'))->body(implode("\n", array_slice($output, -5)))->danger()->send();
        }
        $this->checkScannerToolStatus();
    }

    public function runLynisScan(): void
    {
        if (! $this->lynisInstalled) {
            Notification::make()->title(__('Lynis not installed'))->danger()->send();

            return;
        }

        $this->isScanning = true;
        $this->currentScan = 'lynis';
        $this->scanOutput = __('Running Lynis system audit...')."\n";

        $scanDir = storage_path('app/security-scans');
        if (! is_dir($scanDir)) {
            mkdir($scanDir, 0755, true);
        }

        exec('lynis audit system --no-colors --quick 2>&1', $output, $code);
        $this->scanOutput = implode("\n", $output);

        $results = $this->parseLynisOutput($output);
        $results['scan_time'] = date('Y-m-d H:i:s');
        $results['raw_output'] = $this->scanOutput;

        file_put_contents("$scanDir/lynis-latest.json", json_encode($results, JSON_PRETTY_PRINT));

        $this->lynisResults = $results;
        $this->lastLynisScan = $results['scan_time'];
        $this->isScanning = false;
        $this->currentScan = '';

        $warningCount = count($results['warnings'] ?? []);
        $suggestionCount = count($results['suggestions'] ?? []);

        Notification::make()
            ->title(__('Lynis scan completed'))
            ->body(__('Found :warnings warnings and :suggestions suggestions', ['warnings' => $warningCount, 'suggestions' => $suggestionCount]))
            ->success()
            ->send();
    }

    protected function parseLynisOutput(array $output): array
    {
        $results = [
            'hardening_index' => 0,
            'warnings' => [],
            'suggestions' => [],
            'tests_performed' => 0,
        ];

        $fullOutput = implode("\n", $output);

        if (preg_match('/Hardening index\s*:\s*(\d+)/i', $fullOutput, $matches)) {
            $results['hardening_index'] = (int) $matches[1];
        }

        if (preg_match('/Tests performed\s*:\s*(\d+)/i', $fullOutput, $matches)) {
            $results['tests_performed'] = (int) $matches[1];
        }

        preg_match_all('/\[WARNING\]\s*(.+)$/m', $fullOutput, $warningMatches);
        $results['warnings'] = $warningMatches[1] ?? [];

        preg_match_all('/\[SUGGESTION\]\s*(.+)$/m', $fullOutput, $suggestionMatches);
        $results['suggestions'] = $suggestionMatches[1] ?? [];

        return $results;
    }

    public function getLocalWordPressSites(): array
    {
        $sites = [];

        try {
            $users = \App\Models\User::where('is_admin', false)->get();

            foreach ($users as $user) {
                $result = $this->getAgent()->wpList($user->username);
                $userSites = $result['sites'] ?? [];

                foreach ($userSites as $site) {
                    $siteId = $site['domain'].($site['path'] ?? '');
                    $sites[$siteId] = $site['domain'].($site['path'] !== '/' ? ($site['path'] ?? '') : '');
                }
            }
        } catch (Exception $e) {
            // Return empty array on error
        }

        return $sites;
    }

    public function runWpscanOnSite(): void
    {
        if (! $this->wpscanInstalled) {
            Notification::make()->title(__('WPScan not installed'))->danger()->send();

            return;
        }

        if (! $this->selectedWpSiteId) {
            Notification::make()->title(__('Please select a WordPress site'))->danger()->send();

            return;
        }

        $url = 'https://'.$this->selectedWpSiteId;

        $this->isScanning = true;
        $this->currentScan = 'wpscan';
        $this->scanOutput = __('Scanning WordPress site: :url', ['url' => $url])."\n";

        $scanDir = storage_path('app/security-scans');
        if (! is_dir($scanDir)) {
            mkdir($scanDir, 0755, true);
        }

        // Set HOME to writable directory for wpscan cache
        $wpscanCmd = 'HOME=/var/www wpscan --url '.escapeshellarg($url).' --format json --no-banner 2>&1';
        exec($wpscanCmd, $output, $code);

        $jsonOutput = implode("\n", $output);
        $this->scanOutput = $jsonOutput;

        $results = json_decode($jsonOutput, true);
        if (! $results) {
            $results = [
                'error' => __('Failed to parse scan results'),
                'raw_output' => $jsonOutput,
            ];
        }

        $results['scan_time'] = date('Y-m-d H:i:s');
        $results['target_url'] = $url;

        file_put_contents("$scanDir/wpscan-latest.json", json_encode($results, JSON_PRETTY_PRINT));

        $this->wpscanResults = $results;
        $this->lastWpscanScan = $results['scan_time'];
        $this->isScanning = false;
        $this->currentScan = '';

        Notification::make()
            ->title(__('WPScan completed'))
            ->body(__('Scan finished for :url', ['url' => $url]))
            ->success()
            ->send();
    }

    public function runNiktoScan(): void
    {
        if (! $this->niktoInstalled) {
            Notification::make()->title(__('Nikto not installed'))->danger()->send();

            return;
        }

        $target = 'localhost';

        $this->isScanning = true;
        $this->currentScan = 'nikto';
        $this->scanOutput = __('Scanning local web server...')."\n";

        $scanDir = storage_path('app/security-scans');
        if (! is_dir($scanDir)) {
            mkdir($scanDir, 0755, true);
        }

        $jsonFile = "$scanDir/nikto-".date('Y-m-d-His').'.json';
        // Use full path for nikto since timeout command has restricted PATH
        $niktoPath = file_exists('/usr/bin/nikto') ? '/usr/bin/nikto' : '/usr/local/bin/nikto';
        exec("timeout 300 {$niktoPath} -h localhost -Format json -output {$jsonFile} 2>&1", $output, $code);

        $this->scanOutput = implode("\n", $output);

        $results = [];
        if (file_exists($jsonFile)) {
            $results = json_decode(file_get_contents($jsonFile), true) ?? [];
        }

        if (empty($results)) {
            $results = $this->parseNiktoTextOutput($output);
        }

        $results['scan_time'] = date('Y-m-d H:i:s');
        $results['target'] = $target;
        $results['raw_output'] = $this->scanOutput;

        file_put_contents("$scanDir/nikto-latest.json", json_encode($results, JSON_PRETTY_PRINT));

        $this->niktoResults = $results;
        $this->lastNiktoScan = $results['scan_time'];
        $this->isScanning = false;
        $this->currentScan = '';

        Notification::make()
            ->title(__('Nikto scan completed'))
            ->body(__('Local web server scan finished'))
            ->success()
            ->send();
    }

    protected function parseNiktoTextOutput(array $output): array
    {
        $results = [
            'vulnerabilities' => [],
            'info' => [],
        ];

        foreach ($output as $line) {
            if (preg_match('/^\+\s*OSVDB-\d+:\s*(.+)/', $line, $matches)) {
                $results['vulnerabilities'][] = trim($matches[1]);
            } elseif (preg_match('/^\+\s*(.+)/', $line, $matches)) {
                $results['info'][] = trim($matches[1]);
            }
        }

        return $results;
    }

    // ClamAV on-demand scan methods
    public function getClamScanUsers(): array
    {
        $users = [];
        try {
            $systemUsers = \App\Models\User::where('is_admin', false)->get();
            foreach ($systemUsers as $user) {
                $users[$user->username] = $user->username.' ('.$user->email.')';
            }
        } catch (Exception $e) {
            // Return empty array on error
        }

        return $users;
    }

    public function runClamScanUser(): void
    {
        if (! $this->clamavInstalled) {
            Notification::make()->title(__('ClamAV not installed'))->danger()->send();

            return;
        }

        if (! $this->selectedClamUser) {
            Notification::make()->title(__('Please select a user'))->danger()->send();

            return;
        }

        $this->isScanning = true;
        $this->currentScan = 'clamav';
        $this->scanOutput = __('Scanning user directory: /home/:user', ['user' => $this->selectedClamUser])."\n";

        $scanDir = storage_path('app/security-scans');
        if (! is_dir($scanDir)) {
            mkdir($scanDir, 0755, true);
        }

        $userDir = "/home/{$this->selectedClamUser}";
        $logFile = "$scanDir/clamscan-{$this->selectedClamUser}-".date('Y-m-d-His').'.log';

        $cmd = "clamscan -r --infected --log={$logFile} ".
               "--exclude-dir='^/home/{$this->selectedClamUser}/\\.cache' ".
               "--exclude-dir='^/home/{$this->selectedClamUser}/\\.local' ".
               escapeshellarg($userDir).' 2>&1';

        exec($cmd, $output, $code);
        $this->scanOutput = implode("\n", $output);

        $results = $this->parseClamScanOutput($output);
        $results['scan_time'] = date('Y-m-d H:i:s');
        $results['scan_type'] = 'user';
        $results['target'] = $userDir;
        $results['username'] = $this->selectedClamUser;
        $results['raw_output'] = $this->scanOutput;

        file_put_contents("$scanDir/clamscan-latest.json", json_encode($results, JSON_PRETTY_PRINT));

        $this->clamScanResults = $results;
        $this->lastClamScan = $results['scan_time'];
        $this->isScanning = false;
        $this->currentScan = '';

        $infected = $results['infected_files'] ?? 0;
        $message = $infected > 0
            ? __('Found :count infected file(s)', ['count' => $infected])
            : __('No threats detected');

        Notification::make()
            ->title(__('ClamAV scan completed'))
            ->body($message)
            ->color($infected > 0 ? 'danger' : 'success')
            ->send();
    }

    public function runClamScanServer(): void
    {
        if (! $this->clamavInstalled) {
            Notification::make()->title(__('ClamAV not installed'))->danger()->send();

            return;
        }

        $this->isScanning = true;
        $this->currentScan = 'clamav';
        $this->scanOutput = __('Scanning server-wide: /home')."\n".
                           __('This may take a while...')."\n";

        $scanDir = storage_path('app/security-scans');
        if (! is_dir($scanDir)) {
            mkdir($scanDir, 0755, true);
        }

        $logFile = "$scanDir/clamscan-server-".date('Y-m-d-His').'.log';

        $cmd = "clamscan -r --infected --log={$logFile} ".
               "--exclude-dir='^\\.cache' ".
               "--exclude-dir='^\\.local' ".
               '/home 2>&1';

        exec($cmd, $output, $code);
        $this->scanOutput = implode("\n", $output);

        $results = $this->parseClamScanOutput($output);
        $results['scan_time'] = date('Y-m-d H:i:s');
        $results['scan_type'] = 'server';
        $results['target'] = '/home';
        $results['raw_output'] = $this->scanOutput;

        file_put_contents("$scanDir/clamscan-latest.json", json_encode($results, JSON_PRETTY_PRINT));

        $this->clamScanResults = $results;
        $this->lastClamScan = $results['scan_time'];
        $this->isScanning = false;
        $this->currentScan = '';

        $infected = $results['infected_files'] ?? 0;
        $message = $infected > 0
            ? __('Found :count infected file(s)', ['count' => $infected])
            : __('No threats detected');

        Notification::make()
            ->title(__('Server-wide scan completed'))
            ->body($message)
            ->color($infected > 0 ? 'danger' : 'success')
            ->send();
    }

    protected function parseClamScanOutput(array $output): array
    {
        $results = [
            'scanned_files' => 0,
            'infected_files' => 0,
            'threats' => [],
        ];

        $fullOutput = implode("\n", $output);

        if (preg_match('/Scanned files:\s*(\d+)/i', $fullOutput, $matches)) {
            $results['scanned_files'] = (int) $matches[1];
        }
        if (preg_match('/Infected files:\s*(\d+)/i', $fullOutput, $matches)) {
            $results['infected_files'] = (int) $matches[1];
        }

        foreach ($output as $line) {
            if (preg_match('/^(.+?):\s*(.+?)\s*FOUND$/i', $line, $matches)) {
                $results['threats'][] = [
                    'file' => trim($matches[1]),
                    'threat' => trim($matches[2]),
                ];
            }
        }

        return $results;
    }

    protected function loadClamScanResults(): void
    {
        $scanDir = storage_path('app/security-scans');
        if (file_exists("$scanDir/clamscan-latest.json")) {
            $this->lastClamScan = date('Y-m-d H:i:s', filemtime("$scanDir/clamscan-latest.json"));
            $this->clamScanResults = json_decode(file_get_contents("$scanDir/clamscan-latest.json"), true) ?? [];
        }
    }

    // Dynamic component builders for pure Filament UI
    protected function buildClamavScanResultsSchema(): array
    {
        if (empty($this->clamScanResults)) {
            return [Text::make(__('No scan results available'))];
        }

        $scannedFiles = $this->clamScanResults['scanned_files'] ?? 0;
        $infectedFiles = $this->clamScanResults['infected_files'] ?? 0;
        $scanType = $this->clamScanResults['scan_type'] ?? 'unknown';
        $target = $scanType === 'user' ? ($this->clamScanResults['username'] ?? '-') : __('Server');
        $threats = $this->clamScanResults['threats'] ?? [];

        $components = [
            Grid::make(['default' => 1, 'md' => 3])
                ->schema([
                    Section::make((string) $scannedFiles)
                        ->description(__('Files Scanned'))
                        ->icon('heroicon-o-document-magnifying-glass')
                        ->iconColor('primary'),
                    Section::make((string) $infectedFiles)
                        ->description(__('Infected Files'))
                        ->icon('heroicon-o-exclamation-triangle')
                        ->iconColor($infectedFiles > 0 ? 'danger' : 'success'),
                    Section::make($target)
                        ->description(__('Scan Target'))
                        ->icon('heroicon-o-folder')
                        ->iconColor('gray'),
                ]),
        ];

        if (! empty($threats)) {
            $threatComponents = [];
            foreach ($threats as $threat) {
                $threatComponents[] = Text::make($threat['threat'].': '.basename($threat['file']));
            }
            $components[] = Section::make(__('Threats Detected').' ('.count($threats).')')
                ->icon('heroicon-o-exclamation-triangle')
                ->iconColor('danger')
                ->schema($threatComponents);
        } else {
            $components[] = Section::make(__('No threats detected'))
                ->icon('heroicon-o-check-circle')
                ->iconColor('success')
                ->description(__('The scanned directory appears to be clean.'));
        }

        return $components;
    }

    protected function buildSshCurrentConfigSchema(): array
    {
        return [
            Section::make($this->sshPasswordAuth ? __('Enabled') : __('Disabled'))
                ->description(__('Password Authentication'))
                ->icon('heroicon-o-key')
                ->iconColor($this->sshPasswordAuth ? 'warning' : 'success')
                ->aside(),
            Section::make($this->sshPubkeyAuth ? __('Enabled') : __('Disabled'))
                ->description(__('Public Key Authentication'))
                ->icon('heroicon-o-finger-print')
                ->iconColor($this->sshPubkeyAuth ? 'success' : 'danger')
                ->aside(),
            Section::make((string) $this->sshPort)
                ->description(__('SSH Port'))
                ->icon('heroicon-o-server')
                ->iconColor('gray')
                ->aside(),
        ];
    }

    protected function buildSshRecommendationsSchema(): array
    {
        $keysOnly = ! $this->sshPasswordAuth && $this->sshPubkeyAuth;

        return [
            Section::make(__('Disable password authentication'))
                ->description(__('Use SSH keys only for better security'))
                ->icon($keysOnly ? 'heroicon-o-check-circle' : 'heroicon-o-exclamation-triangle')
                ->iconColor($keysOnly ? 'success' : 'warning')
                ->aside(),
            Section::make(__('Enable Fail2ban protection'))
                ->description(__('Automatically block brute-force attempts'))
                ->icon($this->fail2banRunning ? 'heroicon-o-check-circle' : 'heroicon-o-exclamation-triangle')
                ->iconColor($this->fail2banRunning ? 'success' : 'warning')
                ->aside(),
        ];
    }

    protected function buildClamScanOutputSchema(): array
    {
        $output = $this->clamScanResults['raw_output'] ?? '';

        if ($this->isScanning && $this->currentScan === 'clamav') {
            $output = $this->scanOutput;
        }

        if (! $output) {
            return [];
        }

        return [
            Text::make($output),
        ];
    }

    protected function buildScanOutputSchema(): array
    {
        if (! $this->scanOutput) {
            return [];
        }

        return [
            Text::make($this->scanOutput),
        ];
    }
}
