using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using System.Windows.Media;
using AxCopilot.Models;
using AxCopilot.Services;
using AxCopilot.Themes;
using AxCopilot.Views;

namespace AxCopilot.ViewModels;

public partial class SettingsViewModel : INotifyPropertyChanged
{
    private readonly SettingsService _service;
    internal SettingsService Service => _service;

    // ─── 작업 복사본 ───────────────────────────────────────────────────────
    private string _hotkey;
    private int    _maxResults;
    private double _opacity;
    private string _selectedThemeKey;
    private string _launcherPosition;
    private string _webSearchEngine;
    private bool   _snippetAutoExpand;
    private string _language;
    private string _indexSpeed;

    // 기능 토글
    private bool _showNumberBadges;
    private bool _enableFavorites;
    private bool _enableRecent;
    private bool _enableActionMode;
    private bool _closeOnFocusLost;
    private bool _rememberPosition;
    private bool _showPrefixBadge;
    private bool _enableIconAnimation;
    private bool _enableRainbowGlow;
    private bool _enableSelectionGlow;
    private bool _enableRandomPlaceholder;
    private bool _showLauncherBorder;
    private bool _shortcutHelpUseThemeColor;

    // LLM 공통 설정
    private string _llmService;
    private bool   _llmStreaming;
    private int    _llmMaxContextTokens;
    private int    _llmRetentionDays;
    private double _llmTemperature;

    // 서비스별 독립 설정
    private string _ollamaEndpoint = "http://localhost:11434";
    private string _ollamaApiKey = "";
    private string _ollamaModel = "";
    private string _vllmEndpoint = "";
    private string _vllmApiKey = "";
    private string _vllmModel = "";
    private string _geminiApiKey = "";
    private string _geminiModel = "gemini-2.5-flash";
    private string _claudeApiKey = "";
    private string _claudeModel = "claude-sonnet-4-6";

    // ─── 이벤트 ───────────────────────────────────────────────────────────
    public event EventHandler? ThemePreviewRequested;
    public event EventHandler? SaveCompleted;

    public SettingsViewModel(SettingsService service)
    {
        _service = service;
        var s = service.Settings;

        _hotkey           = s.Hotkey;
        _maxResults       = s.Launcher.MaxResults;
        _opacity          = s.Launcher.Opacity;
        _selectedThemeKey = (s.Launcher.Theme ?? "system").ToLowerInvariant();
        _launcherPosition = s.Launcher.Position;
        _webSearchEngine  = s.Launcher.WebSearchEngine;
        _snippetAutoExpand = s.Launcher.SnippetAutoExpand;
        _language         = s.Launcher.Language;
        _indexSpeed       = s.IndexSpeed ?? "normal";

        // 기능 토글 로드
        _showNumberBadges = s.Launcher.ShowNumberBadges;
        _enableFavorites  = s.Launcher.EnableFavorites;
        _enableRecent     = s.Launcher.EnableRecent;
        _enableActionMode = s.Launcher.EnableActionMode;
        _closeOnFocusLost = s.Launcher.CloseOnFocusLost;
        _rememberPosition = s.Launcher.RememberPosition;
        _showPrefixBadge          = s.Launcher.ShowPrefixBadge;
        _enableIconAnimation      = s.Launcher.EnableIconAnimation;
        _enableRainbowGlow        = s.Launcher.EnableRainbowGlow;
        _enableSelectionGlow      = s.Launcher.EnableSelectionGlow;
        _enableRandomPlaceholder  = s.Launcher.EnableRandomPlaceholder;
        _showLauncherBorder       = s.Launcher.ShowLauncherBorder;
        _shortcutHelpUseThemeColor = s.Launcher.ShortcutHelpUseThemeColor;
        _enableTextAction           = s.Launcher.EnableTextAction;
        // v1.7.1: 파일 대화상자 통합 기본값을 false로 변경 (브라우저 업로드 오작동 방지)
        // 기존 저장값이 true이면 false로 재설정
        _enableFileDialogIntegration = false;
        s.Launcher.EnableFileDialogIntegration = false;
        _enableClipboardAutoCategory = s.Launcher.EnableClipboardAutoCategory;
        _maxPinnedClipboardItems     = s.Launcher.MaxPinnedClipboardItems;
        _textActionTranslateLanguage = s.Launcher.TextActionTranslateLanguage;
        _maxSubAgents        = s.Llm.MaxSubAgents;
        _pdfExportPath       = s.Llm.PdfExportPath;
        _tipDurationSeconds  = s.Llm.TipDurationSeconds;

        // LLM 설정 로드
        var llm = s.Llm;
        _llmService          = llm.Service;
        _llmStreaming        = llm.Streaming;
        _llmMaxContextTokens = llm.MaxContextTokens;
        _llmRetentionDays    = llm.RetentionDays;
        _llmTemperature      = llm.Temperature;
        _defaultAgentPermission = llm.DefaultAgentPermission;
        _defaultOutputFormat    = llm.DefaultOutputFormat;
        _defaultMood            = string.IsNullOrEmpty(llm.DefaultMood) ? "modern" : llm.DefaultMood;
        _autoPreview            = llm.AutoPreview;
        _maxAgentIterations     = llm.MaxAgentIterations > 0 ? llm.MaxAgentIterations : 25;
        _maxRetryOnError        = llm.MaxRetryOnError > 0 ? llm.MaxRetryOnError : 3;
        _agentLogLevel          = llm.AgentLogLevel;
        _agentDecisionLevel     = llm.AgentDecisionLevel;
        _planMode               = string.IsNullOrEmpty(llm.PlanMode) ? "off" : llm.PlanMode;
        _enableMultiPassDocument = llm.EnableMultiPassDocument;
        _enableCoworkVerification = llm.EnableCoworkVerification;
        _enableFilePathHighlight = llm.EnableFilePathHighlight;
        _folderDataUsage        = string.IsNullOrEmpty(llm.FolderDataUsage) ? "active" : llm.FolderDataUsage;
        _enableAuditLog         = llm.EnableAuditLog;
        _enableAgentMemory      = llm.EnableAgentMemory;
        _enableProjectRules     = llm.EnableProjectRules;
        _maxMemoryEntries       = llm.MaxMemoryEntries;
        _enableImageInput       = llm.EnableImageInput;
        _maxImageSizeKb         = llm.MaxImageSizeKb > 0 ? llm.MaxImageSizeKb : 5120;
        _enableToolHooks        = llm.EnableToolHooks;
        _toolHookTimeoutMs      = llm.ToolHookTimeoutMs > 0 ? llm.ToolHookTimeoutMs : 10000;
        _enableSkillSystem      = llm.EnableSkillSystem;
        _skillsFolderPath       = llm.SkillsFolderPath;
        _slashPopupPageSize     = llm.SlashPopupPageSize > 0 ? Math.Clamp(llm.SlashPopupPageSize, 3, 10) : 6;
        _enableDragDropAiActions = llm.EnableDragDropAiActions;
        _dragDropAutoSend       = llm.DragDropAutoSend;
        _enableCodeReview       = llm.Code.EnableCodeReview;
        _enableAutoRouter       = llm.EnableAutoRouter;
        _autoRouterConfidence   = llm.AutoRouterConfidence;
        _enableChatRainbowGlow  = llm.EnableChatRainbowGlow;
        _notifyOnComplete       = llm.NotifyOnComplete;
        _showTips               = llm.ShowTips;
        _devMode                = llm.DevMode;  // 저장된 설정 유지 (한 번 켜면 유지, 끄면 하위 기능 비활성)
        _devModeStepApproval    = llm.DevModeStepApproval;
        _workflowVisualizer     = llm.WorkflowVisualizer;
        _freeTierMode           = llm.FreeTierMode;
        _freeTierDelaySeconds   = llm.FreeTierDelaySeconds > 0 ? llm.FreeTierDelaySeconds : 4;
        _showTotalCallStats     = llm.ShowTotalCallStats;

        // 서비스별 독립 설정 로드
        _ollamaEndpoint = llm.OllamaEndpoint;
        _ollamaModel    = llm.OllamaModel;
        _vllmEndpoint   = llm.VllmEndpoint;
        _vllmModel      = llm.VllmModel;
        _geminiModel    = string.IsNullOrEmpty(llm.GeminiModel) ? "gemini-2.5-flash" : llm.GeminiModel;
        _claudeModel    = string.IsNullOrEmpty(llm.ClaudeModel) ? "claude-sonnet-4-6" : llm.ClaudeModel;

        // API 키 로드: 서비스별 독립 저장
        _geminiApiKey = llm.GeminiApiKey;
        _claudeApiKey = llm.ClaudeApiKey;
        if (llm.EncryptionEnabled)
        {
            _ollamaApiKey = string.IsNullOrEmpty(llm.OllamaApiKey) ? "" : "(저장됨)";
            _vllmApiKey   = string.IsNullOrEmpty(llm.VllmApiKey) ? "" : "(저장됨)";
        }
        else
        {
            _ollamaApiKey = llm.OllamaApiKey;
            _vllmApiKey   = llm.VllmApiKey;
        }

        // 기존 단일 설정에서 마이그레이션 (최초 1회)
        if (string.IsNullOrEmpty(llm.OllamaEndpoint) && !string.IsNullOrEmpty(llm.Endpoint) && llm.Service == "ollama")
        {
            _ollamaEndpoint = llm.Endpoint;
            _ollamaModel = llm.Model;
            if (!llm.EncryptionEnabled) _ollamaApiKey = llm.EncryptedApiKey;
        }
        if (string.IsNullOrEmpty(llm.VllmEndpoint) && !string.IsNullOrEmpty(llm.Endpoint) && llm.Service == "vllm")
        {
            _vllmEndpoint = llm.Endpoint;
            _vllmModel = llm.Model;
            if (!llm.EncryptionEnabled) _vllmApiKey = llm.EncryptedApiKey;
        }
        if (string.IsNullOrEmpty(llm.GeminiApiKey) && !string.IsNullOrEmpty(llm.ApiKey) && llm.Service == "gemini")
        {
            _geminiApiKey = llm.ApiKey;
            _geminiModel = llm.Model;
        }
        if (string.IsNullOrEmpty(llm.ClaudeApiKey) && !string.IsNullOrEmpty(llm.ApiKey) && llm.Service == "claude")
        {
            _claudeApiKey = llm.ApiKey;
            _claudeModel = llm.Model;
        }

        // 차단 경로/확장자 로드
        foreach (var p in llm.BlockedPaths) BlockedPaths.Add(p);
        foreach (var e in llm.BlockedExtensions) BlockedExtensions.Add(e);

        // 등록 모델 로드
        foreach (var rm in llm.RegisteredModels)
            RegisteredModels.Add(new RegisteredModelRow
            {
                Alias = rm.Alias,
                EncryptedModelName = rm.EncryptedModelName,
                Service = rm.Service,
                Endpoint = rm.Endpoint,
                ApiKey = rm.ApiKey,
                AuthType = rm.AuthType ?? "bearer",
                Cp4dUrl = rm.Cp4dUrl ?? "",
                Cp4dUsername = rm.Cp4dUsername ?? "",
                Cp4dPassword = rm.Cp4dPassword ?? "",
            });

        // 프롬프트 템플릿 로드
        foreach (var pt in llm.PromptTemplates)
            PromptTemplates.Add(new PromptTemplateRow { Name = pt.Name, Content = pt.Content, Icon = pt.Icon });

        foreach (var card in ThemeCards)
            card.IsSelected = card.Key == _selectedThemeKey;

        // 알림 설정 로드
        _reminderEnabled         = s.Reminder.Enabled;
        _reminderCorner          = s.Reminder.Corner;
        _reminderIntervalMinutes = s.Reminder.IntervalMinutes;
        _reminderDisplaySeconds  = s.Reminder.DisplaySeconds;

        // 캡처 설정 로드
        _capPrefix              = string.IsNullOrWhiteSpace(s.ScreenCapture.Prefix) ? "cap" : s.ScreenCapture.Prefix;
        _capGlobalHotkeyEnabled = s.ScreenCapture.GlobalHotkeyEnabled;
        _capGlobalHotkey        = string.IsNullOrWhiteSpace(s.ScreenCapture.GlobalHotkey) ? "PrintScreen" : s.ScreenCapture.GlobalHotkey;
        _capGlobalMode          = string.IsNullOrWhiteSpace(s.ScreenCapture.GlobalHotkeyMode) ? "screen" : s.ScreenCapture.GlobalHotkeyMode;
        _capScrollDelayMs       = s.ScreenCapture.ScrollDelayMs > 0 ? s.ScreenCapture.ScrollDelayMs : 120;

        // 클립보드 히스토리 설정 로드
        _clipboardEnabled  = s.ClipboardHistory.Enabled;
        _clipboardMaxItems = s.ClipboardHistory.MaxItems;

        // 시스템 명령 설정 로드
        var sys = s.SystemCommands;
        _sysShowLock       = sys.ShowLock;
        _sysShowSleep      = sys.ShowSleep;
        _sysShowRestart    = sys.ShowRestart;
        _sysShowShutdown   = sys.ShowShutdown;
        _sysShowHibernate  = sys.ShowHibernate;
        _sysShowLogout     = sys.ShowLogout;
        _sysShowRecycleBin = sys.ShowRecycleBin;

        // 시스템 명령 별칭 로드
        var ca = sys.CommandAliases;
        _aliasLock      = FormatAliases(ca, "lock");
        _aliasSleep     = FormatAliases(ca, "sleep");
        _aliasRestart   = FormatAliases(ca, "restart");
        _aliasShutdown  = FormatAliases(ca, "shutdown");
        _aliasHibernate = FormatAliases(ca, "hibernate");
        _aliasLogout    = FormatAliases(ca, "logout");
        _aliasRecycle   = FormatAliases(ca, "recycle");

        // 인덱스 경로 로드
        foreach (var path in s.IndexPaths)
            IndexPaths.Add(path);

        // 인덱스 확장자 로드
        foreach (var ext in s.IndexExtensions)
            IndexExtensions.Add(ext);

        // 전용 핫키 로드
        foreach (var h in s.CustomHotkeys)
            CustomHotkeys.Add(new HotkeyRowModel { Hotkey = h.Hotkey, Target = h.Target, Label = h.Label, Type = h.Type });

        // 스니펫 로드
        foreach (var sn in s.Snippets)
            Snippets.Add(new SnippetRowModel { Key = sn.Key, Name = sn.Name, Content = sn.Content });

        // 배치 명령 로드
        foreach (var alias in s.Aliases.Where(a => a.Type == "batch"))
        {
            BatchCommands.Add(new BatchCommandModel
            {
                Key        = alias.Key,
                Command    = alias.Target,
                ShowWindow = alias.ShowWindow
            });
        }

        // 기존 aliases 로드 (app/url/folder type만)
        foreach (var alias in s.Aliases.Where(a => a.Type is "app" or "url" or "folder"))
        {
            AppShortcuts.Add(new AppShortcutModel
            {
                Key         = alias.Key,
                Description = alias.Description ?? "",
                Target      = alias.Target,
                Type        = alias.Type
            });
        }

        var c = s.Launcher.CustomTheme ?? new CustomThemeColors();
        ColorRows = new List<ColorRowModel>
        {
            new("런처 배경",       nameof(CustomThemeColors.LauncherBackground),     c.LauncherBackground),
            new("항목 배경",       nameof(CustomThemeColors.ItemBackground),         c.ItemBackground),
            new("선택 항목 배경",  nameof(CustomThemeColors.ItemSelectedBackground), c.ItemSelectedBackground),
            new("호버 배경",       nameof(CustomThemeColors.ItemHoverBackground),    c.ItemHoverBackground),
            new("기본 텍스트",     nameof(CustomThemeColors.PrimaryText),           c.PrimaryText),
            new("보조 텍스트",     nameof(CustomThemeColors.SecondaryText),         c.SecondaryText),
            new("플레이스홀더",    nameof(CustomThemeColors.PlaceholderText),       c.PlaceholderText),
            new("강조색",         nameof(CustomThemeColors.AccentColor),           c.AccentColor),
            new("구분선",         nameof(CustomThemeColors.SeparatorColor),        c.SeparatorColor),
            new("힌트 배경",      nameof(CustomThemeColors.HintBackground),        c.HintBackground),
            new("힌트 텍스트",    nameof(CustomThemeColors.HintText),              c.HintText),
            new("테두리",         nameof(CustomThemeColors.BorderColor),           c.BorderColor),
            new("스크롤바",       nameof(CustomThemeColors.ScrollbarThumb),        c.ScrollbarThumb),
            new("그림자",         nameof(CustomThemeColors.ShadowColor),           c.ShadowColor),
        };

        _customWindowCornerRadius = c.WindowCornerRadius;
        _customItemCornerRadius   = c.ItemCornerRadius;
    }
}
