using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using AxCopilot.Services;
using AxCopilot.ViewModels;

namespace AxCopilot.Views;

public partial class SettingsWindow
{
    // ─── 등록 모델 관리 ──────────────────────────────────────────────────

    private bool IsEncryptionEnabled =>
        CurrentApp?.SettingsService?.Settings.Llm.EncryptionEnabled ?? false;

    /// <summary>현재 선택된 서비스 서브탭 이름을 반환합니다.</summary>
    private string GetCurrentServiceSubTab()
    {
        if (SvcTabOllama?.IsChecked == true) return "ollama";
        if (SvcTabVllm?.IsChecked == true) return "vllm";
        if (SvcTabGemini?.IsChecked == true) return "gemini";
        if (SvcTabClaude?.IsChecked == true) return "claude";
        return _vm.LlmService; // 폴백
    }

    private void BtnBrowseSkillFolder_Click(object sender, RoutedEventArgs e)
    {
        var dlg = new System.Windows.Forms.FolderBrowserDialog
        {
            Description = "스킬 파일이 있는 폴더를 선택하세요",
            ShowNewFolderButton = true,
        };
        if (!string.IsNullOrEmpty(_vm.SkillsFolderPath) && System.IO.Directory.Exists(_vm.SkillsFolderPath))
            dlg.SelectedPath = _vm.SkillsFolderPath;
        if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            _vm.SkillsFolderPath = dlg.SelectedPath;
    }

    private void BtnOpenSkillFolder_Click(object sender, RoutedEventArgs e)
    {
        // 기본 스킬 폴더 열기 (사용자 앱데이터)
        var folder = !string.IsNullOrEmpty(_vm.SkillsFolderPath) && System.IO.Directory.Exists(_vm.SkillsFolderPath)
            ? _vm.SkillsFolderPath
            : System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "skills");
        if (!System.IO.Directory.Exists(folder)) System.IO.Directory.CreateDirectory(folder);
        try { System.Diagnostics.Process.Start("explorer.exe", folder); } catch (Exception) { }
    }

    // ─── 스킬 가져오기/내보내기 ──────────────────────────────────────────

    private void SkillImport_Click(object sender, MouseButtonEventArgs e)
    {
        var dlg = new Microsoft.Win32.OpenFileDialog
        {
            Filter = "스킬 패키지 (*.zip)|*.zip",
            Title = "가져올 스킬 zip 파일을 선택하세요",
        };
        if (dlg.ShowDialog() != true) return;

        var count = Services.Agent.SkillService.ImportSkills(dlg.FileName);
        if (count > 0)
            CustomMessageBox.Show($"스킬 {count}개를 성공적으로 가져왔습니다.\n스킬 목록이 갱신됩니다.", "스킬 가져오기");
        else
            CustomMessageBox.Show("스킬 가져오기에 실패했습니다.\nzip 파일에 .skill.md 또는 SKILL.md 파일이 포함되어야 합니다.", "스킬 가져오기");
    }

    private void SkillExport_Click(object sender, MouseButtonEventArgs e)
    {
        var skills = Services.Agent.SkillService.Skills;
        if (skills.Count == 0)
        {
            CustomMessageBox.Show("내보낼 스킬이 없습니다.", "스킬 내보내기");
            return;
        }

        // 스킬 선택 팝업
        var popup = new Window
        {
            WindowStyle = WindowStyle.None,
            AllowsTransparency = true,
            Background = Brushes.Transparent,
            SizeToContent = SizeToContent.WidthAndHeight,
            WindowStartupLocation = WindowStartupLocation.CenterOwner,
            Owner = this,
            MaxHeight = 450,
        };

        var bgBrush = TryFindResource("LauncherBackground") as Brush ?? Brushes.White;
        var fgBrush = TryFindResource("PrimaryText") as Brush ?? Brushes.Black;
        var subFgBrush = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;

        var outer = new Border
        {
            Background = bgBrush,
            CornerRadius = new CornerRadius(12),
            Padding = new Thickness(20),
            MinWidth = 360,
            Effect = new System.Windows.Media.Effects.DropShadowEffect
            {
                BlurRadius = 20, ShadowDepth = 4, Opacity = 0.3,
                Color = Colors.Black,
            },
        };
        var mainPanel = new StackPanel();
        mainPanel.Children.Add(new TextBlock
        {
            Text = "내보낼 스킬 선택",
            FontSize = 15,
            FontWeight = FontWeights.SemiBold,
            Foreground = fgBrush,
            Margin = new Thickness(0, 0, 0, 12),
        });

        var checkBoxes = new List<(CheckBox cb, Services.Agent.SkillDefinition skill)>();
        var listPanel = new StackPanel();
        foreach (var skill in skills)
        {
            var cb = new CheckBox
            {
                Content = $"/{skill.Name} — {skill.Label}",
                FontSize = 12.5,
                Foreground = fgBrush,
                Margin = new Thickness(0, 3, 0, 3),
                IsChecked = false,
            };
            checkBoxes.Add((cb, skill));
            listPanel.Children.Add(cb);
        }
        var scrollViewer = new ScrollViewer
        {
            Content = listPanel,
            MaxHeight = 280,
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
        };
        mainPanel.Children.Add(scrollViewer);

        // 버튼 행
        var btnRow = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            HorizontalAlignment = HorizontalAlignment.Right,
            Margin = new Thickness(0, 14, 0, 0),
        };
        var cancelBtn = new Border
        {
            Background = ThemeResourceHelper.HexBrush("#F0F1F5"),
            CornerRadius = new CornerRadius(8),
            Padding = new Thickness(16, 7, 16, 7),
            Margin = new Thickness(0, 0, 8, 0),
            Cursor = Cursors.Hand,
            Child = new TextBlock { Text = "취소", FontSize = 12, Foreground = subFgBrush },
        };
        cancelBtn.MouseLeftButtonUp += (_, _) => popup.Close();
        btnRow.Children.Add(cancelBtn);

        var okBtn = new Border
        {
            Background = ThemeResourceHelper.HexBrush("#4B5EFC"),
            CornerRadius = new CornerRadius(8),
            Padding = new Thickness(16, 7, 16, 7),
            Cursor = Cursors.Hand,
            Child = new TextBlock { Text = "내보내기", FontSize = 12, FontWeight = FontWeights.SemiBold, Foreground = Brushes.White },
        };
        okBtn.MouseLeftButtonUp += (_, _) =>
        {
            var selected = checkBoxes.Where(x => x.cb.IsChecked == true).Select(x => x.skill).ToList();
            if (selected.Count == 0)
            {
                CustomMessageBox.Show("내보낼 스킬을 선택하세요.", "스킬 내보내기");
                return;
            }

            // 저장 폴더 선택
            var folderDlg = new System.Windows.Forms.FolderBrowserDialog
            {
                Description = "스킬 zip을 저장할 폴더를 선택하세요",
            };
            if (folderDlg.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;

            int exported = 0;
            foreach (var skill in selected)
            {
                var result = Services.Agent.SkillService.ExportSkill(skill, folderDlg.SelectedPath);
                if (result != null) exported++;
            }

            popup.Close();
            if (exported > 0)
                CustomMessageBox.Show($"{exported}개 스킬을 내보냈습니다.\n경로: {folderDlg.SelectedPath}", "스킬 내보내기");
            else
                CustomMessageBox.Show("내보내기에 실패했습니다.", "스킬 내보내기");
        };
        btnRow.Children.Add(okBtn);
        mainPanel.Children.Add(btnRow);

        outer.Child = mainPanel;
        popup.Content = outer;
        popup.KeyDown += (_, ke) => { if (ke.Key == Key.Escape) popup.Close(); };
        popup.ShowDialog();
    }

    private void BtnAddModel_Click(object sender, RoutedEventArgs e)
    {
        var currentService = GetCurrentServiceSubTab();
        var dlg = new ModelRegistrationDialog(currentService);
        dlg.Owner = this;
        if (dlg.ShowDialog() == true)
        {
            _vm.RegisteredModels.Add(new ViewModels.RegisteredModelRow
            {
                Alias = dlg.ModelAlias,
                EncryptedModelName = Services.CryptoService.EncryptIfEnabled(dlg.ModelName, IsEncryptionEnabled),
                Service = currentService,
                Endpoint = dlg.Endpoint,
                ApiKey = Services.CryptoService.EncryptIfEnabled(dlg.ApiKey, IsEncryptionEnabled),
                AuthType = dlg.AuthType,
                Cp4dUrl = dlg.Cp4dUrl,
                Cp4dUsername = dlg.Cp4dUsername,
                Cp4dPassword = Services.CryptoService.EncryptIfEnabled(dlg.Cp4dPassword, IsEncryptionEnabled),
            });
            BuildFallbackModelsPanel();
        }
    }

    private void BtnEditModel_Click(object sender, RoutedEventArgs e)
    {
        if (sender is not Button btn || btn.Tag is not ViewModels.RegisteredModelRow row) return;

        string currentModel  = Services.CryptoService.DecryptIfEnabled(row.EncryptedModelName, IsEncryptionEnabled);
        string currentApiKey = Services.CryptoService.DecryptIfEnabled(row.ApiKey ?? "", IsEncryptionEnabled);
        string cp4dPw        = Services.CryptoService.DecryptIfEnabled(row.Cp4dPassword ?? "", IsEncryptionEnabled);

        var currentService = GetCurrentServiceSubTab();
        var dlg = new ModelRegistrationDialog(currentService, row.Alias, currentModel,
            row.Endpoint, currentApiKey,
            row.AuthType ?? "bearer", row.Cp4dUrl ?? "", row.Cp4dUsername ?? "", cp4dPw);
        dlg.Owner = this;
        if (dlg.ShowDialog() == true)
        {
            row.Alias = dlg.ModelAlias;
            row.EncryptedModelName = Services.CryptoService.EncryptIfEnabled(dlg.ModelName, IsEncryptionEnabled);
            row.Service = currentService;
            row.Endpoint = dlg.Endpoint;
            row.ApiKey = Services.CryptoService.EncryptIfEnabled(dlg.ApiKey, IsEncryptionEnabled);
            row.AuthType = dlg.AuthType;
            row.Cp4dUrl = dlg.Cp4dUrl;
            row.Cp4dUsername = dlg.Cp4dUsername;
            row.Cp4dPassword = Services.CryptoService.EncryptIfEnabled(dlg.Cp4dPassword, IsEncryptionEnabled);
            BuildFallbackModelsPanel();
        }
    }

    private void BtnDeleteModel_Click(object sender, RoutedEventArgs e)
    {
        if (sender is not Button btn || btn.Tag is not ViewModels.RegisteredModelRow row) return;
        var result = CustomMessageBox.Show($"'{row.Alias}' 모델을 삭제하시겠습니까?", "모델 삭제",
            MessageBoxButton.YesNo, MessageBoxImage.Question);
        if (result == MessageBoxResult.Yes)
        {
            _vm.RegisteredModels.Remove(row);
            BuildFallbackModelsPanel();
        }
    }

    // ─── 프롬프트 템플릿 관리 ────────────────────────────────────────────

    private void BtnAddTemplate_Click(object sender, RoutedEventArgs e)
    {
        var dlg = new PromptTemplateDialog();
        dlg.Owner = this;
        if (dlg.ShowDialog() == true)
        {
            _vm.PromptTemplates.Add(new ViewModels.PromptTemplateRow
            {
                Name = dlg.TemplateName,
                Content = dlg.TemplateContent,
            });
        }
    }

    private void BtnEditTemplate_Click(object sender, RoutedEventArgs e)
    {
        if (sender is not Button btn || btn.Tag is not ViewModels.PromptTemplateRow row) return;
        var dlg = new PromptTemplateDialog(row.Name, row.Content);
        dlg.Owner = this;
        if (dlg.ShowDialog() == true)
        {
            row.Name = dlg.TemplateName;
            row.Content = dlg.TemplateContent;
        }
    }

    private void BtnDeleteTemplate_Click(object sender, RoutedEventArgs e)
    {
        if (sender is not Button btn || btn.Tag is not ViewModels.PromptTemplateRow row) return;
        var result = CustomMessageBox.Show($"'{row.Name}' 템플릿을 삭제하시겠습니까?", "템플릿 삭제",
            MessageBoxButton.YesNo, MessageBoxImage.Question);
        if (result == MessageBoxResult.Yes)
            _vm.PromptTemplates.Remove(row);
    }
}
