<?php

namespace App\Services\MobileConfig;

use App\Models\MobileSetting;
use App\Models\SystemSetting;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class MobileConfigService
{
    private const CACHE_KEY = 'mobile_config_all';

    private const DEFINITIONS = [
        // 1. BRANDING
        'app_name' => ['type' => 'string', 'group' => 'branding', 'default' => 'biiproject'],
        'app_tagline' => ['type' => 'string', 'group' => 'branding', 'default' => 'Smart Solution for Your Business'],
        'app_icon_url' => ['type' => 'image_path', 'group' => 'branding', 'default' => null],
        'logo_url' => ['type' => 'image_path', 'group' => 'branding', 'default' => null],
        'splash_image_url' => ['type' => 'image_path', 'group' => 'branding', 'default' => null],
        'brand_color' => ['type' => 'string', 'group' => 'branding', 'default' => '#C6F135'],
        'theme_color_primary' => ['type' => 'string', 'group' => 'branding', 'default' => '#C6F135'],
        'theme_color_secondary' => ['type' => 'string', 'group' => 'branding', 'default' => '#1A1A1A'],
        'primary_font_family' => ['type' => 'string', 'group' => 'branding', 'default' => 'Outfit'],

        // 2. CONTROL CENTER
        'kill_switch_active' => ['type' => 'boolean', 'group' => 'control_center', 'default' => false],
        'kill_switch_message' => ['type' => 'string', 'group' => 'control_center', 'default' => 'System is currently undergoing emergency maintenance. Please try again later.'],
        'maintenance_start_at' => ['type' => 'string', 'group' => 'control_center', 'default' => null],
        'maintenance_end_at' => ['type' => 'string', 'group' => 'control_center', 'default' => null],
        'maintenance_bypass_ips' => ['type' => 'string', 'group' => 'control_center', 'default' => '127.0.0.1'],
        'announcement_enabled' => ['type' => 'boolean', 'group' => 'control_center', 'default' => false],
        'announcement_text' => ['type' => 'string', 'group' => 'control_center', 'default' => 'Maintenance is scheduled for tonight at 12:00 AM.'],
        'announcement_type' => ['type' => 'string', 'group' => 'control_center', 'default' => 'info'],

        // 3. APP UPDATES
        'app_version' => ['type' => 'string', 'group' => 'app_updates', 'default' => '2.0.0'],
        'min_app_version' => ['type' => 'string', 'group' => 'app_updates', 'default' => '1.0.0'],
        'onboarding_version' => ['type' => 'string', 'group' => 'app_updates', 'default' => '1.0.0'],
        'store_url_android' => ['type' => 'string', 'group' => 'app_updates', 'default' => 'https://play.google.com/store/apps/details?id=com.biiproject'],
        'store_url_ios' => ['type' => 'string', 'group' => 'app_updates', 'default' => 'https://apps.apple.com/app/biiproject'],
        'store_url_huawei' => ['type' => 'string', 'group' => 'app_updates', 'default' => 'https://appgallery.huawei.com/'],

        // 4. FEATURES
        'enable_registration' => ['type' => 'boolean', 'group' => 'features', 'default' => true],
        'enable_guest_mode' => ['type' => 'boolean', 'group' => 'features', 'default' => false],
        'require_otp_registration' => ['type' => 'boolean', 'group' => 'features', 'default' => false],
        'enable_biometrics' => ['type' => 'boolean', 'group' => 'features', 'default' => false],
        'enable_remember_me' => ['type' => 'boolean', 'group' => 'features', 'default' => true],
        'review_prompt_enabled' => ['type' => 'boolean', 'group' => 'features', 'default' => true],
        'min_actions_before_review' => ['type' => 'integer', 'group' => 'features', 'default' => 10],
        'region_lock_enabled' => ['type' => 'boolean', 'group' => 'features', 'default' => false],

        // 5. SECURITY & AUTH
        'login_title' => ['type' => 'string', 'group' => 'security_auth', 'default' => 'biiproject'],
        'login_subtitle' => ['type' => 'string', 'group' => 'security_auth', 'default' => 'Sign in to continue'],
        'token_ttl_minutes' => ['type' => 'integer', 'group' => 'security_auth', 'default' => 43200],
        'session_max_age' => ['type' => 'integer', 'group' => 'security_auth', 'default' => 86400],
        'login_max_attempts' => ['type' => 'integer', 'group' => 'security_auth', 'default' => 5],
        'biometric_auth_type' => ['type' => 'string', 'group' => 'security_auth', 'default' => 'any'],
        'oauth_google_enabled' => ['type' => 'boolean', 'group' => 'security_auth', 'default' => false],
        'oauth_apple_enabled' => ['type' => 'boolean', 'group' => 'security_auth', 'default' => false],
        'oauth_facebook_enabled' => ['type' => 'boolean', 'group' => 'security_auth', 'default' => false],

        // 6. CONNECTIVITY
        'api_base_url' => ['type' => 'string', 'group' => 'connectivity', 'default' => 'https://api.biiproject.com'],
        'api_version' => ['type' => 'string', 'group' => 'connectivity', 'default' => 'v1'],
        'api_timeout_ms' => ['type' => 'integer', 'group' => 'connectivity', 'default' => 30000],
        'api_retry_count' => ['type' => 'integer', 'group' => 'connectivity', 'default' => 3],
        'request_cache_ttl' => ['type' => 'integer', 'group' => 'connectivity', 'default' => 3600],
        'sync_interval_ms' => ['type' => 'integer', 'group' => 'connectivity', 'default' => 10000],
        'enable_ssl_pinning' => ['type' => 'boolean', 'group' => 'connectivity', 'default' => false],
        'ssl_pinning_hash' => ['type' => 'string', 'group' => 'connectivity', 'default' => null],
        'environment_selector' => ['type' => 'string', 'group' => 'connectivity', 'default' => 'production'],

        // 7. NOTIFICATIONS
        'enable_push_notifications' => ['type' => 'boolean', 'group' => 'notifications', 'default' => true],
        'fcm_topic_default' => ['type' => 'string', 'group' => 'notifications', 'default' => 'all_users'],
        'default_channel_id' => ['type' => 'string', 'group' => 'notifications', 'default' => 'default_channel'],
        'notification_sound_enabled' => ['type' => 'boolean', 'group' => 'notifications', 'default' => true],
        'badge_count_enabled' => ['type' => 'boolean', 'group' => 'notifications', 'default' => true],
        'priority_level' => ['type' => 'string', 'group' => 'notifications', 'default' => 'high'],

        // 8. SUPPORT & SOCIAL
        'support_email' => ['type' => 'string', 'group' => 'support_social', 'default' => 'support@biiproject.com'],
        'support_whatsapp' => ['type' => 'string', 'group' => 'support_social', 'default' => '628123456789'],
        'live_chat_url' => ['type' => 'string', 'group' => 'support_social', 'default' => null],
        'faq_url' => ['type' => 'string', 'group' => 'support_social', 'default' => null],
        'privacy_policy_url' => ['type' => 'string', 'group' => 'support_social', 'default' => 'https://biiproject.com/privacy'],
        'social_instagram_url' => ['type' => 'string', 'group' => 'support_social', 'default' => null],
        'social_twitter_url' => ['type' => 'string', 'group' => 'support_social', 'default' => null],
        'social_facebook_url' => ['type' => 'string', 'group' => 'support_social', 'default' => null],
        'social_youtube_url' => ['type' => 'string', 'group' => 'support_social', 'default' => null],

        // 9. ANALYTICS & SYSTEM
        'crashlytics_enabled' => ['type' => 'boolean', 'group' => 'analytics_system', 'default' => true],
        'log_level' => ['type' => 'string', 'group' => 'analytics_system', 'default' => 'error'],
        'event_sampling_rate' => ['type' => 'string', 'group' => 'analytics_system', 'default' => '1.0'],
        'google_analytics_id' => ['type' => 'string', 'group' => 'analytics_system', 'default' => null],
        'gdpr_compliance_enabled' => ['type' => 'boolean', 'group' => 'analytics_system', 'default' => false],
        'target_sdk_version' => ['type' => 'string', 'group' => 'analytics_system', 'default' => '34'],
        'system_timezone' => ['type' => 'string', 'group' => 'analytics_system', 'default' => 'Asia/Jakarta'],
        'default_locale' => ['type' => 'string', 'group' => 'analytics_system', 'default' => 'en'],

        // 10. DYNAMIC CONTENT
        'dashboard_categories' => ['type' => 'string', 'group' => 'features', 'default' => 'All,Tech,Finance,Health,Coding'],
        'faq_json' => ['type' => 'json', 'group' => 'support_social', 'default' => '[{"q":"How to sync?","a":"Click the sync button on dashboard."}]'],
        'help_topics_json' => ['type' => 'json', 'group' => 'support_social', 'default' => '[{"id":"1","name":"Account","icon":"user"},{"id":"2","name":"System","icon":"cpu"}]'],
    ];

    public static function getDefinitions(): array
    {
        return self::DEFINITIONS;
    }

    public function all(bool $refresh = false): array
    {
        if ($refresh) {
            $this->clearCache();
        }

        return Cache::remember(self::CACHE_KEY, now()->addHours(24), function () {
            $settings = MobileSetting::all();
            $config = [];

            // 1. Initialize from definitions
            foreach (self::DEFINITIONS as $key => $def) {
                if (! isset($config[$def['group']])) {
                    $config[$def['group']] = [];
                }
                $config[$def['group']][$key] = $def['default'];
            }

            // 2. Fallback from Global System Settings (Branding)
            // This ensures if mobile settings are empty, we use the main site branding
            if (class_exists(SystemSetting::class)) {
                $systemSettings = SystemSetting::whereIn('key', ['app_name', 'app_logo', 'app_tagline', 'app_tagline1', 'app_tagline2'])
                    ->pluck('value', 'key');

                if ($systemSettings->has('app_name')) {
                    $config['branding']['app_name'] = $systemSettings->get('app_name');
                    $config['security_auth']['login_title'] = $systemSettings->get('app_name');
                }

                if ($systemSettings->has('app_logo')) {
                    $logoPath = $systemSettings->get('app_logo');
                    $logoUrl = Str::startsWith($logoPath, 'http') ? $logoPath : asset($logoPath);
                    $config['branding']['logo_url'] = $logoUrl;
                }

                if ($systemSettings->has('app_tagline')) {
                    $config['security_auth']['login_subtitle'] = strip_tags($systemSettings->get('app_tagline'));
                    $config['branding']['app_tagline'] = strip_tags($systemSettings->get('app_tagline'));
                }
            }

            // 3. Overlay with Mobile-Specific settings (Overwrites fallbacks)
            foreach ($settings as $setting) {
                $value = $this->castValue($setting->value, $setting->type);

                // Handle Assets (Storage URLs)
                if ($setting->type === 'image_path' && $value && ! Str::startsWith($value, 'http')) {
                    $value = asset($value);
                }

                $group = $setting->group;

                // Skip if value is default/null to keep system fallback
                if (($setting->key === 'logo_url' || $setting->key === 'app_name') && (empty($value) || $value === 'biiproject')) {
                    continue;
                }

                // Handle Localization Dynamic Keys
                if ($group === 'localization') {
                    if (! isset($config['localization'])) {
                        $config['localization'] = ['English' => [], 'Indonesian' => []];
                    }

                    if (str_starts_with($setting->key, 'lang_en_')) {
                        $key = str_replace('lang_en_', '', $setting->key);
                        $config['localization']['English'][$key] = $value;
                    } elseif (str_starts_with($setting->key, 'lang_id_')) {
                        $key = str_replace('lang_id_', '', $setting->key);
                        $config['localization']['Indonesian'][$key] = $value;
                    }

                    continue;
                }

                if (! isset($config[$group])) {
                    $config[$group] = [];
                }

                // Clean HTML tags for mobile display on critical text fields
                if (in_array($setting->key, ['kill_switch_message', 'announcement_text'])) {
                    $value = trim(strip_tags((string) $value));
                }

                $config[$group][$setting->key] = $value;
            }

            return $config;
        });
    }

    public function getGroupedSettingsForAdmin(): array
    {
        $settings = MobileSetting::all()->keyBy('key');
        $grouped = [];

        // 1. Process from Definitions (Ensure defaults)
        foreach (self::DEFINITIONS as $key => $def) {
            $setting = $settings->get($key);

            if (! $setting) {
                $setting = new MobileSetting([
                    'key' => $key,
                    'group' => $def['group'],
                    'type' => $def['type'],
                    'value' => is_bool($def['default']) ? ($def['default'] ? 'true' : 'false') : (string) $def['default'],
                ]);
            }

            if (! isset($grouped[$def['group']])) {
                $grouped[$def['group']] = collect();
            }
            $grouped[$def['group']]->push($setting);
            $settings->forget($key); // Mark as processed
        }

        // 2. Process remaining settings in DB (like dynamic localization keys)
        foreach ($settings as $setting) {
            if (! isset($grouped[$setting->group])) {
                $grouped[$setting->group] = collect();
            }
            $grouped[$setting->group]->push($setting);
        }

        return $grouped;
    }

    /**
     * Get all keys that should be treated as boolean.
     */
    public function getBooleanKeys(): array
    {
        $definitions = collect(self::DEFINITIONS)
            ->filter(fn ($def) => $def['type'] === 'boolean')
            ->keys()
            ->toArray();

        $db = MobileSetting::where('type', 'boolean')->pluck('key')->toArray();

        return array_unique(array_merge($definitions, $db));
    }

    public function update(array $data, array $files = []): void
    {
        \DB::transaction(function () use ($data, $files) {
            $settings = MobileSetting::all()->keyBy('key');

            // Handle Files
            foreach ($files as $key => $file) {
                if ($file instanceof UploadedFile) {
                    $setting = $settings->get($key);
                    $def = self::DEFINITIONS[$key] ?? null;

                    if (! $setting && $def) {
                        $setting = MobileSetting::create([
                            'key' => $key,
                            'group' => $def['group'],
                            'type' => $def['type'],
                        ]);
                        $settings->put($key, $setting); // Sync to collection
                    }

                    if ($setting && $setting->type === 'image_path') {
                        // Delete old file if exists
                        if ($setting->value) {
                            $oldPath = str_replace('/storage/', '', $setting->value);
                            Storage::disk('public')->delete($oldPath);
                        }

                        // OPTIMIZATION: Convert to WebP (only if GD extension is available)
                        $hasGd = function_exists('imagewebp') && function_exists('imagecreatefromstring');
                        $filename = $key.'_'.time().($hasGd ? '.webp' : '.'.$file->getClientOriginalExtension());

                        if ($hasGd) {
                            $tempPath = $file->getRealPath();
                            $content = file_get_contents($tempPath);
                            $image = imagecreatefromstring($content);

                            if ($image) {
                                imagepalettetotruecolor($image);
                                imagealphablending($image, true);
                                imagesavealpha($image, true);

                                // NEW: Auto Resize (Max width 1200px)
                                $width = imagesx($image);
                                $height = imagesy($image);
                                if ($width > 1200) {
                                    $newWidth = 1200;
                                    $newHeight = (int) ($height * (1200 / $width));
                                    $resized = imagecreatetruecolor($newWidth, $newHeight);
                                    imagealphablending($resized, false);
                                    imagesavealpha($resized, true);
                                    imagecopyresampled($resized, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
                                    imagedestroy($image);
                                    $image = $resized;
                                }

                                ob_start();
                                imagewebp($image, null, 80);
                                $webpContent = ob_get_clean();
                                imagedestroy($image);

                                Storage::disk('public')->put('mobile-assets/'.$filename, $webpContent);
                                $data[$key] = '/storage/mobile-assets/'.$filename;
                            } else {
                                $hasGd = false;
                            }
                        }

                        if (! $hasGd) {
                            // Standard store fallback
                            $path = $file->storeAs('mobile-assets', $filename, 'public');
                            $data[$key] = '/storage/'.$path;
                        }
                    }
                }
            }

            // Handle Values
            foreach ($data as $key => $value) {
                $setting = $settings->get($key);
                $def = self::DEFINITIONS[$key] ?? null;

                // Handle dynamic keys (like localization) that are already in DB but not in DEFINITIONS
                if (! $def && ! $setting) {
                    continue;
                }

                if (! $setting && $def) {
                    $setting = MobileSetting::create([
                        'key' => $key,
                        'group' => $def['group'],
                        'type' => $def['type'],
                    ]);
                }

                $newValue = $value;
                if ($setting->type === 'boolean') {
                    $newValue = (filter_var($value, FILTER_VALIDATE_BOOLEAN) || $value === '1' || $value === 'true') ? 'true' : 'false';
                }

                $setting->update(['value' => $newValue]);
            }
        });

        $this->clearCache();
    }

    /**
     * Clear the cache.
     */
    public function clearCache(): void
    {
        self::clearCacheStatic();
    }

    public static function clearCacheStatic(): void
    {
        Cache::forget(self::CACHE_KEY);
    }

    /**
     * Cast raw string value from DB to appropriate PHP type.
     */
    private function castValue(mixed $value, string $type): mixed
    {
        if ($value === null) {
            return null;
        }

        return match ($type) {
            'boolean' => $value === 'true' || $value === '1' || $value === true,
            'int', 'integer' => (int) $value,
            'json' => json_decode($value, true),
            default => $value,
        };
    }
}
