<?php

declare(strict_types=1);

namespace App\Filament\Admin\Pages;

use App\Models\Setting;
use App\Services\Agent\AgentClient;
use BackedEnum;
use Exception;
use Filament\Forms\Components\Select;
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\Section;
use Filament\Support\Icons\Heroicon;
use Illuminate\Contracts\Support\Htmlable;

class Waf extends Page implements HasForms
{
    use InteractsWithForms;

    protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedShieldCheck;

    protected static ?int $navigationSort = 20;

    protected static ?string $slug = 'waf';

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

    public bool $wafInstalled = false;

    public array $wafFormData = [];

    public function getTitle(): string|Htmlable
    {
        return __('ModSecurity / WAF');
    }

    public static function getNavigationLabel(): string
    {
        return __('ModSecurity / WAF');
    }

    public function mount(): void
    {
        $this->wafInstalled = $this->detectWaf();
        $this->wafFormData = [
            'enabled' => Setting::get('waf_enabled', '0') === '1',
            'paranoia' => Setting::get('waf_paranoia', '1'),
            'audit_log' => Setting::get('waf_audit_log', '1') === '1',
        ];
    }

    protected function detectWaf(): bool
    {
        $paths = [
            '/etc/nginx/modsec/main.conf',
            '/etc/nginx/modsecurity.conf',
            '/etc/modsecurity/modsecurity.conf',
            '/etc/modsecurity/modsecurity.conf-recommended',
        ];

        foreach ($paths as $path) {
            if (file_exists($path)) {
                return true;
            }
        }

        return false;
    }

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

    public function wafForm(\Filament\Schemas\Schema $schema): \Filament\Schemas\Schema
    {
        return $schema
            ->statePath('wafFormData')
            ->schema([
                Section::make(__('WAF Settings'))
                    ->schema([
                        Toggle::make('enabled')
                            ->label(__('Enable ModSecurity'))
                            ->disabled(fn () => ! $this->wafInstalled)
                            ->helperText(fn () => $this->wafInstalled ? null : __('ModSecurity is not installed. Install it to enable WAF.')),
                        Select::make('paranoia')
                            ->label(__('Paranoia Level'))
                            ->options([
                                '1' => '1 - Basic',
                                '2' => '2 - Moderate',
                                '3' => '3 - Strict',
                                '4' => '4 - Very Strict',
                            ])
                            ->default('1'),
                        Toggle::make('audit_log')
                            ->label(__('Enable Audit Log')),
                    ])
                    ->columns(2),
            ]);
    }

    public function saveWafSettings(): void
    {
        $data = $this->wafForm->getState();
        $requestedEnabled = ! empty($data['enabled']);
        if ($requestedEnabled && ! $this->wafInstalled) {
            $requestedEnabled = false;
        }

        Setting::set('waf_enabled', $requestedEnabled ? '1' : '0');
        Setting::set('waf_paranoia', (string) ($data['paranoia'] ?? '1'));
        Setting::set('waf_audit_log', ! empty($data['audit_log']) ? '1' : '0');

        try {
            $agent = new AgentClient;
            $agent->wafApplySettings(
                $requestedEnabled,
                (string) ($data['paranoia'] ?? '1'),
                ! empty($data['audit_log'])
            );

            if (! $this->wafInstalled && ! empty($data['enabled'])) {
                Notification::make()
                    ->title(__('ModSecurity is not installed'))
                    ->body(__('WAF was disabled automatically. Install ModSecurity to enable it.'))
                    ->warning()
                    ->send();

                return;
            }

            Notification::make()
                ->title(__('WAF settings applied'))
                ->success()
                ->send();
        } catch (Exception $e) {
            Notification::make()
                ->title(__('WAF settings saved, but apply failed'))
                ->body($e->getMessage())
                ->warning()
                ->send();
        }
    }
}
