using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace AxCopilot.Views;

/// <summary>
/// Ctrl+Shift+P로 호출되는 커맨드 팔레트.
/// 모든 기능에 빠르게 접근할 수 있는 통합 명령 검색 창입니다.
/// </summary>
public partial class CommandPaletteWindow : Window
{
    private readonly Action<string>? _onExecute;
    private readonly List<CommandEntry> _commands = new();
    // 향후 키보드 탐색용
    // private int _selectedIndex = -1;

    public string? SelectedCommand { get; private set; }

    public CommandPaletteWindow(Action<string>? onExecute = null)
    {
        InitializeComponent();
        _onExecute = onExecute;
        RegisterCommands();
        RenderItems("");
        Loaded += (_, _) => { SearchBox.Focus(); };
    }

    private void RegisterCommands()
    {
        // 탭 전환
        _commands.Add(new("Chat 탭으로 전환", "탭 전환", "\uE8BD", "tab:chat"));
        _commands.Add(new("Cowork 탭으로 전환", "탭 전환", "\uE8BD", "tab:cowork"));
        _commands.Add(new("Code 탭으로 전환", "탭 전환", "\uE8BD", "tab:code"));

        // 대화 관리
        _commands.Add(new("새 대화 시작", "대화", "\uE710", "new_conversation"));
        _commands.Add(new("대화 검색", "대화", "\uE721", "search_conversation"));

        // 모델 변경
        _commands.Add(new("모델 변경", "설정", "\uEA86", "change_model"));

        // 프리셋
        _commands.Add(new("프리셋 선택", "프리셋", "\uE71D", "select_preset"));

        // 설정
        _commands.Add(new("설정 열기", "앱", "\uE713", "open_settings"));
        _commands.Add(new("테마 변경", "앱", "\uE790", "change_theme"));
        _commands.Add(new("통계 보기", "앱", "\uE9F9", "open_statistics"));

        // 파일
        _commands.Add(new("작업 폴더 변경", "파일", "\uED25", "change_folder"));
        _commands.Add(new("파일 탐색기 열기", "파일", "\uE8B7", "open_file_explorer"));

        // 에이전트
        _commands.Add(new("개발자 모드 토글", "에이전트", "\uE71C", "toggle_devmode"));
        _commands.Add(new("감사 로그 보기", "에이전트", "\uE9D9", "open_audit_log"));

        // 도구
        _commands.Add(new("클립보드에서 붙여넣기", "도구", "\uE77F", "paste_clipboard"));
        _commands.Add(new("대화 내보내기", "도구", "\uE78C", "export_conversation"));
    }

    private void RenderItems(string query)
    {
        ResultPanel.Children.Clear();

        var filtered = string.IsNullOrWhiteSpace(query)
            ? _commands
            : _commands.Where(c =>
                c.Label.Contains(query, StringComparison.OrdinalIgnoreCase) ||
                c.Category.Contains(query, StringComparison.OrdinalIgnoreCase) ||
                (Core.FuzzyEngine.IsChosung(query) && Core.FuzzyEngine.ContainsChosung(c.Label, query))).ToList();

        for (int i = 0; i < filtered.Count; i++)
        {
            var cmd = filtered[i];
            var idx = i;

            var sp = new StackPanel { Orientation = Orientation.Horizontal };
            sp.Children.Add(new TextBlock
            {
                Text = cmd.Icon, FontFamily = ThemeResourceHelper.SegoeMdl2,
                FontSize = 14, Foreground = FindResource("AccentColor") as Brush ?? Brushes.CornflowerBlue,
                VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 0, 10, 0),
            });
            var textSp = new StackPanel();
            textSp.Children.Add(new TextBlock
            {
                Text = cmd.Label, FontSize = 13,
                Foreground = FindResource("PrimaryText") as Brush ?? Brushes.White,
            });
            textSp.Children.Add(new TextBlock
            {
                Text = cmd.Category, FontSize = 10.5,
                Foreground = FindResource("SecondaryText") as Brush ?? Brushes.Gray,
            });
            sp.Children.Add(textSp);

            var item = new Border
            {
                Child = sp, Background = Brushes.Transparent,
                CornerRadius = new CornerRadius(8), Cursor = Cursors.Hand,
                Padding = new Thickness(10, 8, 14, 8), Margin = new Thickness(0, 1, 0, 1),
            };

            var hoverBg = FindResource("HintBackground") as Brush ?? new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
            item.MouseEnter += (s, _) => { if (s is Border b) b.Background = hoverBg; };
            item.MouseLeave += (s, _) => { if (s is Border b) b.Background = Brushes.Transparent; };
            item.MouseLeftButtonUp += (_, _) => ExecuteCommand(cmd.CommandId);

            ResultPanel.Children.Add(item);
        }
    }

    private void ExecuteCommand(string commandId)
    {
        SelectedCommand = commandId;
        _onExecute?.Invoke(commandId);
        Close();
    }

    private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        RenderItems(SearchBox.Text);
    }

    private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Escape) { Close(); e.Handled = true; }
        else if (e.Key == Key.Enter && ResultPanel.Children.Count > 0)
        {
            // 첫 번째 항목 실행
            var filtered = string.IsNullOrWhiteSpace(SearchBox.Text)
                ? _commands : _commands.Where(c =>
                    c.Label.Contains(SearchBox.Text, StringComparison.OrdinalIgnoreCase) ||
                    c.Category.Contains(SearchBox.Text, StringComparison.OrdinalIgnoreCase)).ToList();
            if (filtered.Count > 0) ExecuteCommand(filtered[0].CommandId);
            e.Handled = true;
        }
    }

    private void Window_Deactivated(object sender, EventArgs e) => Close();

    private record CommandEntry(string Label, string Category, string Icon, string CommandId);
}
