using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using AxCopilot.Services.Agent;

namespace AxCopilot.Views;

/// <summary>스킬 갤러리 창. 설치된 모든 스킬을 카드 형태로 표시하고 관리합니다.</summary>
public partial class SkillGalleryWindow : Window
{
    private string _selectedCategory = "전체";

    public SkillGalleryWindow()
    {
        InitializeComponent();
        Loaded += (_, _) => { BuildCategoryFilter(); RenderSkills(); };
    }

    // ─── 타이틀바 ─────────────────────────────────────────────────────────

    private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // 타이틀바 우측 버튼 영역에서는 DragMove 실행하지 않음
        var pos = e.GetPosition(this);
        if (pos.X > ActualWidth - 160) return; // 우측 버튼 영역 보호

        if (e.ClickCount == 2)
            WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
        else DragMove();
    }

    private void BtnClose_Click(object sender, MouseButtonEventArgs e) => Close();

    // ─── 버튼 ─────────────────────────────────────────────────────────────

    private void BtnAddSkill_Click(object sender, MouseButtonEventArgs e)
    {
        var editor = new SkillEditorWindow { Owner = this };
        if (editor.ShowDialog() == true)
        {
            BuildCategoryFilter();
            RenderSkills();
        }
    }

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

        var count = SkillService.ImportSkills(dlg.FileName);
        if (count > 0)
        {
            CustomMessageBox.Show($"스킬 {count}개를 성공적으로 가져왔습니다.", "스킬 가져오기");
            BuildCategoryFilter();
            RenderSkills();
        }
        else
            CustomMessageBox.Show("스킬 가져오기에 실패했습니다.", "스킬 가져오기");
    }

    // ─── 카테고리 필터 ─────────────────────────────────────────────────────

    private void BuildCategoryFilter()
    {
        CategoryFilterBar.Children.Clear();
        var skills = SkillService.Skills;

        var categories = new[] { "전체" }
            .Concat(skills
                .Select(s => string.IsNullOrEmpty(s.Requires) ? "내장" : "고급 (런타임)")
                .Distinct())
            .ToList();

        // 사용자 스킬이 있으면 추가
        var userFolder = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
            "AxCopilot", "skills");
        var hasUser = skills.Any(s =>
            s.FilePath.StartsWith(userFolder, StringComparison.OrdinalIgnoreCase));
        if (hasUser && !categories.Contains("사용자"))
            categories.Add("사용자");

        foreach (var cat in categories)
        {
            var btn = new Border
            {
                Tag          = cat,
                CornerRadius = new CornerRadius(8),
                Padding      = new Thickness(14, 5, 14, 5),
                Margin       = new Thickness(0, 0, 6, 0),
                Background   = cat == _selectedCategory
                    ? new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC))
                    : TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent,
                Cursor       = Cursors.Hand,
            };
            btn.Child = new TextBlock
            {
                Text       = cat,
                FontSize   = 12,
                FontWeight = FontWeights.SemiBold,
                Foreground = cat == _selectedCategory
                    ? Brushes.White
                    : TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
            };
            btn.MouseLeftButtonUp += (s, _) =>
            {
                if (s is Border b && b.Tag is string tag)
                {
                    _selectedCategory = tag;
                    BuildCategoryFilter();
                    RenderSkills();
                }
            };
            CategoryFilterBar.Children.Add(btn);
        }
    }

    // ─── 스킬 목록 렌더링 ──────────────────────────────────────────────────

    private void RenderSkills()
    {
        SkillListPanel.Children.Clear();
        var skills = FilterSkills(SkillService.Skills);

        var userFolder = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
            "AxCopilot", "skills");

        foreach (var skill in skills)
            SkillListPanel.Children.Add(BuildSkillCard(skill, userFolder));

        if (skills.Count == 0)
            SkillListPanel.Children.Add(new TextBlock
            {
                Text       = "표시할 스킬이 없습니다.",
                FontSize   = 13,
                Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
                Margin     = new Thickness(0, 20, 0, 0),
                HorizontalAlignment = HorizontalAlignment.Center,
            });

        var total = SkillService.Skills.Count;
        var avail = SkillService.Skills.Count(s => s.IsAvailable);
        GalleryStatus.Text = $"총 {total}개 스킬 | 사용 가능 {avail}개 | 런타임 필요 {total - avail}개";
    }

    private List<SkillDefinition> FilterSkills(IReadOnlyList<SkillDefinition> skills)
    {
        var userFolder = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
            "AxCopilot", "skills");

        return _selectedCategory switch
        {
            "내장"        => skills.Where(s => string.IsNullOrEmpty(s.Requires)
                             && !s.FilePath.StartsWith(userFolder, StringComparison.OrdinalIgnoreCase)).ToList(),
            "고급 (런타임)" => skills.Where(s => !string.IsNullOrEmpty(s.Requires)).ToList(),
            "사용자"       => skills.Where(s => s.FilePath.StartsWith(userFolder, StringComparison.OrdinalIgnoreCase)).ToList(),
            _             => skills.ToList(),
        };
    }

    private Border BuildSkillCard(SkillDefinition skill, string userFolder)
    {
        var bgBrush  = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
        var fgBrush  = TryFindResource("PrimaryText")   as Brush ?? Brushes.White;
        var subBrush = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;

        var isUser     = skill.FilePath.StartsWith(userFolder, StringComparison.OrdinalIgnoreCase);
        var isAdvanced = !string.IsNullOrEmpty(skill.Requires);

        var card = new Border
        {
            Background   = bgBrush,
            CornerRadius = new CornerRadius(10),
            Padding      = new Thickness(14, 10, 14, 10),
            Margin       = new Thickness(0, 0, 0, 6),
        };

        var grid = new Grid();
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
        grid.ColumnDefinitions.Add(new ColumnDefinition());
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });

        // ── 아이콘 원 ──
        var iconBorder = new Border
        {
            Width        = 38,
            Height       = 38,
            CornerRadius = new CornerRadius(10),
            Background   = new SolidColorBrush(Color.FromArgb(0x30, 0x4B, 0x5E, 0xFC)),
            Margin       = new Thickness(0, 0, 12, 0),
            VerticalAlignment = VerticalAlignment.Center,
        };
        iconBorder.Child = new TextBlock
        {
            Text       = skill.Icon,
            FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize   = 16,
            Foreground = skill.IsAvailable
                ? new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC))
                : subBrush,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment   = VerticalAlignment.Center,
        };
        Grid.SetColumn(iconBorder, 0);

        // ── 정보 ──
        var infoPanel = new StackPanel { VerticalAlignment = VerticalAlignment.Center };

        // 이름 + 뱃지들
        var nameRow = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 0, 0, 3) };
        nameRow.Children.Add(new TextBlock
        {
            Text       = $"/{skill.Name}",
            FontSize   = 13,
            FontWeight = FontWeights.SemiBold,
            FontFamily = ThemeResourceHelper.Consolas,
            Foreground = skill.IsAvailable
                ? new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC))
                : subBrush,
            Opacity    = skill.IsAvailable ? 1.0 : 0.6,
            VerticalAlignment = VerticalAlignment.Center,
        });
        nameRow.Children.Add(new TextBlock
        {
            Text              = $"  {skill.Label}",
            FontSize          = 12.5,
            Foreground        = fgBrush,
            VerticalAlignment = VerticalAlignment.Center,
        });

        // 소스 뱃지
        if (isUser)
            nameRow.Children.Add(MakeBadge("사용자", "#34D399"));
        else if (isAdvanced)
            nameRow.Children.Add(MakeBadge("고급", "#A78BFA"));
        else
            nameRow.Children.Add(MakeBadge("내장", "#9CA3AF"));

        // 비가용 뱃지
        if (!skill.IsAvailable)
            nameRow.Children.Add(MakeBadge(skill.UnavailableHint, "#F87171"));

        infoPanel.Children.Add(nameRow);
        infoPanel.Children.Add(new TextBlock
        {
            Text         = skill.Description,
            FontSize     = 11.5,
            Foreground   = subBrush,
            TextWrapping = TextWrapping.Wrap,
            Opacity      = skill.IsAvailable ? 1.0 : 0.6,
        });
        Grid.SetColumn(infoPanel, 1);

        // ── 액션 버튼들 ──
        var actions = new StackPanel
        {
            Orientation       = Orientation.Horizontal,
            VerticalAlignment = VerticalAlignment.Center,
            Margin            = new Thickness(8, 0, 0, 0),
        };

        // 편집
        actions.Children.Add(MakeActionBtn("\uE70F", "#3B82F6", isUser ? "편집 (시각적 편집기)" : "편집 (파일 열기)",
            () =>
            {
                if (isUser)
                {
                    var editor = new SkillEditorWindow(skill) { Owner = this };
                    if (editor.ShowDialog() == true)
                    {
                        SkillService.LoadSkills();
                        BuildCategoryFilter();
                        RenderSkills();
                    }
                }
                else
                {
                    try { System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(skill.FilePath) { UseShellExecute = true }); }
                    catch (Exception ex) { CustomMessageBox.Show($"파일을 열 수 없습니다: {ex.Message}", "편집"); }
                }
            }));

        // 복제 (사용자 스킬/폴더 스킬만)
        actions.Children.Add(MakeActionBtn("\uE8C8", "#10B981", "복제",
            () =>
            {
                try
                {
                    var destFolder = Path.Combine(userFolder);
                    if (!Directory.Exists(destFolder)) Directory.CreateDirectory(destFolder);

                    var srcName = Path.GetFileNameWithoutExtension(skill.FilePath);
                    var destPath = Path.Combine(destFolder, $"{srcName}_copy.skill.md");
                    var counter  = 2;
                    while (File.Exists(destPath))
                        destPath = Path.Combine(destFolder, $"{srcName}_copy{counter++}.skill.md");

                    File.Copy(skill.FilePath, destPath);
                    SkillService.LoadSkills();
                    BuildCategoryFilter();
                    RenderSkills();
                }
                catch (Exception ex) { CustomMessageBox.Show($"복제 실패: {ex.Message}", "복제"); }
            }));

        // 내보내기
        actions.Children.Add(MakeActionBtn("\uEDE1", "#F59E0B", "내보내기 (.zip)",
            () =>
            {
                var folderDlg = new System.Windows.Forms.FolderBrowserDialog
                    { Description = "내보낼 폴더를 선택하세요" };
                if (folderDlg.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
                var result = SkillService.ExportSkill(skill, folderDlg.SelectedPath);
                if (result != null)
                    CustomMessageBox.Show($"내보내기 완료:\n{result}", "내보내기");
                else
                    CustomMessageBox.Show("내보내기에 실패했습니다.", "내보내기");
            }));

        // 삭제 (사용자 스킬만)
        if (isUser)
        {
            actions.Children.Add(MakeActionBtn("\uE74D", "#F87171", "삭제",
                () =>
                {
                    var confirm = CustomMessageBox.Show(
                        $"스킬 '/{skill.Name}'을 삭제하시겠습니까?",
                        "스킬 삭제",
                        MessageBoxButton.YesNo, MessageBoxImage.Question);
                    if (confirm != MessageBoxResult.Yes) return;
                    try
                    {
                        File.Delete(skill.FilePath);
                        SkillService.LoadSkills();
                        BuildCategoryFilter();
                        RenderSkills();
                    }
                    catch (Exception ex) { CustomMessageBox.Show($"삭제 실패: {ex.Message}", "삭제"); }
                }));
        }

        Grid.SetColumn(actions, 2);

        grid.Children.Add(iconBorder);
        grid.Children.Add(infoPanel);
        grid.Children.Add(actions);
        card.Child = grid;

        // 호버 효과 + 카드 클릭 → 상세 보기
        card.Cursor = Cursors.Hand;
        card.MouseEnter += (_, _) =>
        {
            card.Background = new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
        };
        card.MouseLeave += (_, _) => card.Background = bgBrush;
        card.MouseLeftButtonUp += (_, e) =>
        {
            // 액션 버튼 클릭은 무시 (버블링 방지)
            if (e.OriginalSource is FrameworkElement src)
            {
                var parent = src;
                while (parent != null)
                {
                    if (parent == actions) return;
                    parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
                }
            }
            ShowSkillDetail(skill);
        };

        return card;
    }

    private Border MakeBadge(string text, string colorHex)
    {
        var col = (Color)ColorConverter.ConvertFromString(colorHex);
        return new Border
        {
            Background   = new SolidColorBrush(Color.FromArgb(0x25, col.R, col.G, col.B)),
            CornerRadius = new CornerRadius(4),
            Padding      = new Thickness(5, 1, 5, 1),
            Margin       = new Thickness(6, 0, 0, 0),
            VerticalAlignment = VerticalAlignment.Center,
            Child = new TextBlock
            {
                Text       = text,
                FontSize   = 9.5,
                FontWeight = FontWeights.SemiBold,
                Foreground = new SolidColorBrush(col),
            },
        };
    }

    private Border MakeActionBtn(string icon, string colorHex, string tooltip, Action action)
    {
        var col = (Color)ColorConverter.ConvertFromString(colorHex);
        var btn = new Border
        {
            Width        = 28,
            Height       = 28,
            CornerRadius = new CornerRadius(6),
            Background   = Brushes.Transparent,
            Cursor       = Cursors.Hand,
            Margin       = new Thickness(2, 0, 0, 0),
            ToolTip      = tooltip,
            Child        = new TextBlock
            {
                Text                = icon,
                FontFamily          = ThemeResourceHelper.SegoeMdl2,
                FontSize            = 12,
                Foreground          = new SolidColorBrush(col),
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment   = VerticalAlignment.Center,
            },
        };
        btn.MouseEnter += (_, _) =>
            btn.Background = new SolidColorBrush(Color.FromArgb(0x20, col.R, col.G, col.B));
        btn.MouseLeave += (_, _) => btn.Background = Brushes.Transparent;
        btn.MouseLeftButtonUp += (_, _) => action();
        return btn;
    }
}
