<?php

namespace App\Http\Requests\SystemSettings;

use Illuminate\Foundation\Http\FormRequest;

class UpdateSystemConfigRequest extends FormRequest
{
    public function authorize(): bool
    {
        $user = $this->user();
        if (!$user) {
            return false;
        }

        // Allow if Developer or legacy manage permission exists
        if ($user->hasRole('Developer') || $user->can('manage global settings')) {
            return true;
        }

        // Allow if any granular manage global settings permission exists (direct or via role)
        return $user->getAllPermissions()
            ->contains(fn ($p) => str_starts_with($p->name, 'manage global settings:'));
    }

    public function rules(): array
    {
        return [
            'app_name' => ['sometimes', 'required', 'string', 'min:3', 'max:100'],
            'app_tagline' => ['nullable', 'string', 'max:150'],
            'app_tagline1' => ['nullable', 'string', 'max:150'],
            'app_tagline2' => ['nullable', 'string', 'max:300'],
            'footer_text' => ['nullable', 'string', 'max:200'],
            'default_locale' => ['nullable', 'string', 'max:10'],
            'instance_mode' => ['nullable', 'string', 'in:Production,Trial,Demo'],
            'app_logo' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
            'app_favicon' => ['nullable', 'image', 'mimes:png,ico,webp', 'max:1024'],
            'enable_landing_page' => ['nullable', 'boolean'],
            'feature_notification_center' => ['nullable', 'boolean'],
            'feature_google_oauth' => ['nullable', 'boolean'],
            'google_client_id' => ['nullable', 'string', 'max:255'],
            'google_client_secret' => ['nullable', 'string', 'max:255'],
            'feature_facebook_oauth' => ['nullable', 'boolean'],
            'facebook_app_id' => ['nullable', 'string', 'max:255'],
            'facebook_app_secret' => ['nullable', 'string', 'max:255'],
            'feature_github_oauth' => ['nullable', 'boolean'],
            'github_client_id' => ['nullable', 'string', 'max:255'],
            'github_client_secret' => ['nullable', 'string', 'max:255'],
            'social_login_callback_url' => ['nullable', 'string', 'max:255'],

            // Regional
            'regional_timezone' => ['nullable', 'string', 'max:100'],
            'regional_date_format' => ['nullable', 'string', 'max:20'],
            'regional_time_format' => ['nullable', 'string', 'max:20'],

            // Login Security
            'login_max_attempts' => ['nullable', 'integer', 'min:1', 'max:20'],
            'login_lockout_duration' => ['nullable', 'integer', 'min:1', 'max:1440'],
            'login_lockout_notify' => ['nullable', 'boolean'],
            'two_factor_auth' => ['nullable', 'boolean'],
            'two_factor_method' => ['nullable', 'string', 'in:email,app'],
            'captcha_enabled' => ['nullable', 'boolean'],
            'captcha_site_key' => ['nullable', 'string', 'max:255'],
            'captcha_secret_key' => ['nullable', 'string', 'max:255'],
            'captcha_version' => ['nullable', 'string', 'in:v2,v3'],
            'login_log_enabled' => ['nullable', 'boolean'],

            // Password Policy
            'password_min_length' => ['nullable', 'integer', 'min:8', 'max:100'],
            'password_max_length' => ['nullable', 'integer', 'min:8', 'max:255'],
            'password_require_uppercase' => ['nullable', 'boolean'],
            'password_require_lowercase' => ['nullable', 'boolean'],
            'password_require_numeric' => ['nullable', 'boolean'],
            'password_require_special' => ['nullable', 'boolean'],
            'password_expiry_days' => ['nullable', 'integer', 'min:0', 'max:365'],
            'password_history_count' => ['nullable', 'integer', 'min:0', 'max:10'],
            'password_reset_link_expiry' => ['nullable', 'integer', 'min:1', 'max:10080'],

            // Session Security
            'session_driver' => ['nullable', 'string', 'in:file,redis,database'],
            'session_lifetime' => ['nullable', 'integer', 'min:1', 'max:10080'],
            'session_single_session' => ['nullable', 'boolean'],
            'session_auto_logout_idle' => ['nullable', 'integer', 'min:1', 'max:10080'],
            'session_allow_remember_me' => ['nullable', 'boolean'],
            'session_remember_me_duration' => ['nullable', 'integer', 'min:1', 'max:365'],
            'session_secure_cookie' => ['nullable', 'boolean'],
            'session_encrypt' => ['nullable', 'boolean'],
            'session_concurrent_limit' => ['nullable', 'integer', 'min:0', 'max:50'],

            // WebAuthn
            'two_factor_trust_days' => ['nullable', 'integer', 'min:1', 'max:365'],
            'webauthn_enabled' => ['nullable', 'boolean'],

            // IP & Access Control
            'ip_whitelist_admin' => ['nullable', 'string'],
            'ip_blacklist' => ['nullable', 'string'],
            'rate_limit_per_ip' => ['nullable', 'integer', 'min:1', 'max:1000'],
            'auto_block_ip' => ['nullable', 'boolean'],
            'threshold_auto_block' => ['nullable', 'integer', 'min:1', 'max:5000'],
            'force_https' => ['nullable', 'boolean'],
            'hsts_enabled' => ['nullable', 'boolean'],
            'cors_origins' => ['nullable', 'string'],
            'cors_methods' => ['nullable', 'string'],
            'cors_headers' => ['nullable', 'string'],

            // Notifications
            'mail_driver' => ['nullable', 'string', 'in:smtp,mailgun,ses,mail'],
            'mail_host' => ['nullable', 'string', 'max:255'],
            'mail_port' => ['nullable', 'integer', 'min:1', 'max:65535'],
            'mail_username' => ['nullable', 'string', 'max:255'],
            'mail_password' => ['nullable', 'string', 'max:255'],
            'mail_encryption' => ['nullable', 'string', 'in:tls,ssl,null'],
            'mail_from_address' => ['nullable', 'email', 'max:255'],
            'mail_from_name' => ['nullable', 'string', 'max:255'],
            'telegram_bot_token' => ['nullable', 'string', 'max:255'],
            'telegram_chat_id' => ['nullable', 'string', 'max:255'],

            // Backups
            'backup_db_enabled' => ['nullable', 'boolean'],
            'backup_db_driver' => ['nullable', 'string', 'in:local,s3,gdrive'],
            'backup_db_frequency' => ['nullable', 'string', 'in:hourly,daily,weekly,monthly'],
            'backup_db_time' => ['nullable', 'string', 'regex:/^[0-9]{2}:[0-9]{2}$/'],
            'backup_db_retention' => ['nullable', 'integer', 'min:1', 'max:365'],
            'backup_db_compress' => ['nullable', 'boolean'],
            'backup_db_encrypt' => ['nullable', 'boolean'],
            'backup_db_encrypt_key' => ['nullable', 'string', 'min:32', 'max:255'],
            'backup_db_exclude' => ['nullable', 'string'],
            'backup_db_notify_on' => ['nullable', 'string', 'in:success,failed,both,none'],
            'backup_db_notify_to' => ['nullable', 'string', 'max:255'],

            // Google Drive Backups
            'gdrive_client_id' => ['nullable', 'string', 'max:500'],
            'gdrive_client_secret' => ['nullable', 'string', 'max:500'],
            'gdrive_refresh_token' => ['nullable', 'string', 'max:1000'],
            'gdrive_folder' => ['nullable', 'string', 'max:255'],

            // S3 Backups
            's3_key' => ['nullable', 'string', 'max:255'],
            's3_secret' => ['nullable', 'string', 'max:255'],
            's3_region' => ['nullable', 'string', 'max:100'],
            's3_bucket' => ['nullable', 'string', 'max:255'],
            's3_endpoint' => ['nullable', 'string', 'max:500'],

            // Maintenance Mode
            'maintenance_mode_enabled' => ['nullable', 'boolean'],
            'maintenance_mode_message' => ['nullable', 'string', 'max:1000'],
            'maintenance_mode_title' => ['nullable', 'string', 'max:200'],
            'maintenance_mode_secret' => ['nullable', 'string', 'alpha_dash', 'max:100'],
            'maintenance_mode_allowed_ips' => ['nullable', 'string'],
            'maintenance_mode_end_at' => ['nullable', 'date'],
            'maintenance_mode_retry' => ['nullable', 'integer', 'min:0', 'max:3600'],
            'maintenance_mode_image' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],

            // Content & Legal
            'page_help_content' => ['nullable', 'string'],
            'page_tos_content' => ['nullable', 'string'],
            'page_privacy_content' => ['nullable', 'string'],
            'page_about_content' => ['nullable', 'string'],
            'page_security_content' => ['nullable', 'string'],
            'require_pdp_on_registration' => ['nullable', 'boolean'],
            'feature_cookie_banner' => ['nullable', 'boolean'],
            'pdp_document_version' => ['nullable', 'integer', 'min:1'],
            'tos_document_version' => ['nullable', 'integer', 'min:1'],
            'pdp_dpo_email' => ['nullable', 'email', 'max:255'],
            'pdp_company_address' => ['nullable', 'string', 'max:500'],

            // AI Configuration
            'ai_enabled' => ['nullable', 'boolean'],
            'ai_provider' => ['nullable', 'string', 'in:gpt,gemini,claude,deepseek,grok,mistral,ollama,openrouter'],
            'ai_gpt_key' => ['nullable', 'string', 'max:255'],
            'ai_gemini_key' => ['nullable', 'string', 'max:255'],
            'ai_claude_key' => ['nullable', 'string', 'max:255'],
            'ai_deepseek_key' => ['nullable', 'string', 'max:255'],
            'ai_grok_key' => ['nullable', 'string', 'max:255'],
            'ai_mistral_key' => ['nullable', 'string', 'max:255'],
            'ai_ollama_base_url' => ['nullable', 'string', 'max:255'],
            'ai_openrouter_key' => ['nullable', 'string', 'max:255'],
            'ai_default_model' => ['nullable', 'string', 'max:100'],
            'ai_system_instruction' => ['nullable', 'string', 'max:5000'],
            'ai_temperature' => ['nullable', 'numeric', 'min:0', 'max:2'],
            'ai_max_tokens' => ['nullable', 'integer', 'min:1', 'max:32000'],

            // SAP RFC Configuration
            'sap_rfc_ashost' => ['nullable', 'string', 'max:255'],
            'sap_rfc_sysnr' => ['nullable', 'string', 'max:20'],
            'sap_rfc_client' => ['nullable', 'string', 'max:20'],
            'sap_rfc_user' => ['nullable', 'string', 'max:255'],
            'sap_rfc_passwd' => ['nullable', 'string', 'max:255'],
            'sap_rfc_router' => ['nullable', 'string', 'max:255'],
            'sap_rfc_trace' => ['nullable', 'string', 'in:0,1,2'],
            'engine_pulse_enabled' => ['nullable', 'boolean'],
            'engine_telescope_enabled' => ['nullable', 'boolean'],
            'engine_swagger_enabled' => ['nullable', 'boolean'],
            'engine_horizon_enabled' => ['nullable', 'boolean'],
            'ai_healing_enabled' => ['nullable', 'boolean'],
        ];
    }

    protected function prepareForValidation(): void
    {
        $booleans = [
            'feature_notification_center',
            'feature_google_oauth',
            'feature_facebook_oauth',
            'feature_github_oauth',
            'login_lockout_notify',
            'two_factor_auth',
            'captcha_enabled',
            'login_log_enabled',
            'password_require_uppercase',
            'password_require_lowercase',
            'password_require_numeric',
            'password_require_special',
            'webauthn_enabled',
            'session_single_session',
            'session_allow_remember_me',
            'session_secure_cookie',
            'session_encrypt',
            'auto_block_ip',
            'force_https',
            'hsts_enabled',
            'backup_db_enabled',
            'backup_db_compress',
            'backup_db_encrypt',
            'maintenance_mode_enabled',
            'require_pdp_on_registration',
            'feature_cookie_banner',
            'ai_enabled',
            'enable_landing_page',
            'engine_pulse_enabled',
            'engine_telescope_enabled',
            'engine_swagger_enabled',
            'engine_horizon_enabled',
            'ai_healing_enabled',
        ];

        $updates = [];
        foreach ($booleans as $key) {
            $updates[$key] = $this->boolean($key);
        }

        if (!empty($updates)) {
            $this->merge($updates);
        }
    }
}
