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

namespace AxCopilot.Views;

/// <summary>스킬 시각적 편집기. 새 스킬 생성 또는 기존 스킬 편집을 GUI로 지원합니다.</summary>
public partial class SkillEditorWindow : Window
{
    // ── 아이콘 후보 목록 (Segoe MDL2 Assets 코드포인트) ──
    private static readonly string[] IconCandidates =
    [
        "\uE70F", // Edit
        "\uE8A5", // Document
        "\uE943", // Code
        "\uE74C", // Search
        "\uE8B7", // Folder
        "\uE896", // People
        "\uE713", // Settings
        "\uE753", // Cloud
        "\uE774", // Camera
        "\uE8D6", // Mail
        "\uE8F1", // Lightbulb
        "\uE7C3", // Data
        "\uECA7", // Rocket
        "\uE71E", // Chart
        "\uE8C8", // Copy
        "\uE8F6", // Process
        "\uE81E", // Link
        "\uEBD2", // AI
        "\uE9D9", // Globe
        "\uE77B", // Shield
    ];

    private string _selectedIcon = "\uE70F";
    private SkillDefinition? _editingSkill;
    private readonly ToolRegistry _toolRegistry;

    /// <summary>새 스킬 모드로 열기.</summary>
    public SkillEditorWindow()
    {
        InitializeComponent();
        _toolRegistry = ToolRegistry.CreateDefault();
        Loaded += (_, _) => { BuildIconSelector(); BuildToolChecklist(); UpdatePreview(); };
    }

    /// <summary>편집 모드로 열기.</summary>
    public SkillEditorWindow(SkillDefinition skill) : this()
    {
        _editingSkill = skill;
        Loaded += (_, _) => LoadSkill(skill);
    }

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

    private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // 타이틀바 우측 닫기 버튼 영역에서는 DragMove 실행하지 않음
        var pos = e.GetPosition(this);
        if (pos.X > ActualWidth - 50) 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 BtnCancel_Click(object sender, MouseButtonEventArgs e) => Close();

    // ─── 아이콘 선택기 ────────────────────────────────────────────────────

    private void BuildIconSelector()
    {
        IconSelectorPanel.Children.Clear();
        var accentBrush = new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC));
        var subBrush = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
        var bgBrush = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;

        foreach (var icon in IconCandidates)
        {
            var isSelected = icon == _selectedIcon;
            var border = new Border
            {
                Width        = 34,
                Height       = 34,
                CornerRadius = new CornerRadius(8),
                Margin       = new Thickness(0, 0, 4, 4),
                Cursor       = Cursors.Hand,
                Background   = isSelected ? accentBrush : bgBrush,
                BorderBrush  = isSelected ? accentBrush : Brushes.Transparent,
                BorderThickness = new Thickness(1.5),
                Tag          = icon,
            };
            border.Child = new TextBlock
            {
                Text                = icon,
                FontFamily          = ThemeResourceHelper.SegoeMdl2,
                FontSize            = 14,
                Foreground          = isSelected ? Brushes.White : subBrush,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment   = VerticalAlignment.Center,
            };
            border.MouseLeftButtonUp += (s, _) =>
            {
                if (s is Border b && b.Tag is string ic)
                {
                    _selectedIcon = ic;
                    BuildIconSelector();
                }
            };
            // 호버
            var capturedIcon = icon;
            border.MouseEnter += (s, _) =>
            {
                if (s is Border b && capturedIcon != _selectedIcon)
                    b.Background = new SolidColorBrush(Color.FromArgb(0x30, 0x4B, 0x5E, 0xFC));
            };
            border.MouseLeave += (s, _) =>
            {
                if (s is Border b && capturedIcon != _selectedIcon)
                    b.Background = bgBrush;
            };

            IconSelectorPanel.Children.Add(border);
        }
    }

    // ─── 도구 체크리스트 ──────────────────────────────────────────────────

    private void BuildToolChecklist()
    {
        ToolCheckListPanel.Children.Clear();
        var tools = _toolRegistry.All.OrderBy(t => t.Name).ToList();
        var fgBrush = TryFindResource("PrimaryText") as Brush ?? Brushes.White;
        var subBrush = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;

        // 기존 스킬 편집 시 활성 도구 파싱
        var activeTools = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        if (_editingSkill != null && !string.IsNullOrWhiteSpace(_editingSkill.AllowedTools))
        {
            foreach (var t in _editingSkill.AllowedTools.Split(',', StringSplitOptions.RemoveEmptyEntries))
                activeTools.Add(t.Trim());
        }

        foreach (var tool in tools)
        {
            var cb = new CheckBox
            {
                Tag       = tool.Name,
                IsChecked = activeTools.Count == 0 || activeTools.Contains(tool.Name),
                Margin    = new Thickness(0, 0, 0, 4),
                Style     = TryFindResource("ToggleSwitch") as Style,
            };

            var row = new StackPanel
            {
                Orientation = Orientation.Horizontal,
                Margin      = new Thickness(0, 0, 0, 2),
            };
            row.Children.Add(cb);
            row.Children.Add(new TextBlock
            {
                Text              = tool.Name,
                FontSize          = 11.5,
                FontFamily        = ThemeResourceHelper.Consolas,
                Foreground        = fgBrush,
                VerticalAlignment = VerticalAlignment.Center,
                Margin            = new Thickness(6, 0, 0, 0),
            });

            // 설명 툴팁
            if (!string.IsNullOrEmpty(tool.Description))
                row.ToolTip = tool.Description;

            ToolCheckListPanel.Children.Add(row);
        }
    }

    /// <summary>체크된 도구 이름 목록을 가져옵니다.</summary>
    private List<string> GetCheckedTools()
    {
        var result = new List<string>();
        foreach (var child in ToolCheckListPanel.Children)
        {
            if (child is StackPanel row && row.Children.Count > 0 && row.Children[0] is CheckBox cb)
            {
                if (cb.IsChecked == true && cb.Tag is string name)
                    result.Add(name);
            }
        }
        return result;
    }

    // ─── 템플릿 삽입 ──────────────────────────────────────────────────────

    private void BtnInsertTemplate_Click(object sender, MouseButtonEventArgs e)
    {
        if (sender is not FrameworkElement el || el.Tag is not string tag) return;

        var template = tag switch
        {
            "tools" => BuildToolListTemplate(),
            "format" => """
                ## 출력 형식

                1. 결과를 사용자에게 한국어로 설명합니다.
                2. 코드 블록은 마크다운 형식으로 감쌉니다.
                3. 핵심 정보를 먼저 제시하고, 세부 사항은 뒤에 붙입니다.
                """,
            "steps" => """
                ## 실행 단계

                1. **분석**: 사용자의 요청을 분석합니다.
                2. **계획**: 수행할 작업을 계획합니다.
                3. **실행**: 도구를 사용하여 작업을 수행합니다.
                4. **검증**: 결과를 검증합니다.
                5. **보고**: 결과를 사용자에게 보고합니다.
                """,
            _ => "",
        };

        if (string.IsNullOrEmpty(template)) return;

        var insertPos = TxtInstructions.CaretIndex;
        var prefix = insertPos > 0 && TxtInstructions.Text.Length > 0
            && TxtInstructions.Text[insertPos - 1] != '\n' ? "\n\n" : "";
        TxtInstructions.Text = TxtInstructions.Text.Insert(insertPos, prefix + template.Trim());
        TxtInstructions.CaretIndex = insertPos + prefix.Length + template.Trim().Length;
        TxtInstructions.Focus();
    }

    private string BuildToolListTemplate()
    {
        var checkedTools = GetCheckedTools();
        if (checkedTools.Count == 0)
            return "## 사용 가능한 도구\n\n(도구가 선택되지 않았습니다. 우측 패널에서 도구를 선택하세요.)";

        var lines = new List<string> { "## 사용 가능한 도구", "" };
        foreach (var toolName in checkedTools)
        {
            var tool = _toolRegistry.All.FirstOrDefault(t => t.Name == toolName);
            if (tool != null)
                lines.Add($"- **{tool.Name}**: {tool.Description}");
        }
        return string.Join("\n", lines);
    }

    // ─── 미리보기 업데이트 ────────────────────────────────────────────────

    private void TxtInstructions_TextChanged(object sender, TextChangedEventArgs e) => UpdatePreview();

    private void UpdatePreview()
    {
        if (PreviewTokens == null || PreviewFileName == null) return;

        var content = GenerateSkillContent();
        var tokens = TokenEstimator.Estimate(content);
        PreviewTokens.Text = $"예상 토큰: ~{tokens:N0}자  |  {content.Length:N0}자";

        var name = string.IsNullOrWhiteSpace(TxtName?.Text) ? "new-skill" : TxtName.Text.Trim();
        PreviewFileName.Text = $"{name}.skill.md";
    }

    // ─── 스킬 콘텐츠 생성 ────────────────────────────────────────────────

    private string GenerateSkillContent()
    {
        var name = TxtName?.Text?.Trim() ?? "new-skill";
        var label = TxtLabel?.Text?.Trim() ?? "";
        var desc = TxtDescription?.Text?.Trim() ?? "";
        var instructions = TxtInstructions?.Text ?? "";

        // 런타임 요구사항
        var requiresTag = "";
        if (CmbRequires?.SelectedItem is ComboBoxItem cbi && cbi.Tag is string req && !string.IsNullOrEmpty(req))
            requiresTag = req;

        // 도구 목록
        var checkedTools = GetCheckedTools();
        var allToolCount = _toolRegistry.All.Count;
        var allowedToolsStr = checkedTools.Count < allToolCount
            ? string.Join(", ", checkedTools)
            : ""; // 전체 선택이면 비워둠

        // YAML 프론트매터 생성
        var yaml = new List<string> { "---" };
        yaml.Add($"name: {name}");
        if (!string.IsNullOrEmpty(label)) yaml.Add($"label: {label}");
        if (!string.IsNullOrEmpty(desc)) yaml.Add($"description: {desc}");
        yaml.Add($"icon: {_selectedIcon}");
        if (!string.IsNullOrEmpty(requiresTag)) yaml.Add($"requires: {requiresTag}");
        if (!string.IsNullOrEmpty(allowedToolsStr)) yaml.Add($"allowed-tools: {allowedToolsStr}");
        yaml.Add("---");
        yaml.Add("");

        return string.Join("\n", yaml) + instructions;
    }

}
