using System.Windows;
using System.Windows.Input;
using AxCopilot.Services;
using AxCopilot.ViewModels;

namespace AxCopilot.Views;

public partial class LauncherWindow
{
    // ─── IME 보완 검색 ────────────────────────────────────────────────────────

    /// <summary>
    /// WPF 바인딩(UpdateSourceTrigger=PropertyChanged)은 한글 IME 조합 중에는
    /// ViewModel 업데이트를 지연하므로, TextChanged에서 직접 검색을 트리거합니다.
    /// InputText 프로퍼티를 건드리지 않아 IME 조합 상태(音節)가 유지됩니다.
    /// </summary>
    private void InputBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
    {
        // 바인딩이 이미 ViewModel을 업데이트한 경우(조합 완료 후)에는 중복 실행 방지
        if (_vm.InputText == InputBox.Text) return;
        // 조합 중 텍스트로 즉시 검색 — InputText 바인딩 우회
        _ = _vm.TriggerImeSearchAsync(InputBox.Text);
    }

    // ─── 키보드 이벤트 ────────────────────────────────────────────────────────

    /// <summary>
    /// Window 레벨 PreviewKeyDown — 터널링으로 먼저 실행되므로
    /// TextBox 내부 ScrollViewer가 Up/Down을 소비하기 전에 인터셉트합니다.
    /// </summary>
    private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        bool shift = (Keyboard.Modifiers & ModifierKeys.Shift) != 0;

        switch (e.Key)
        {
            case Key.Escape:
                if (_vm.IsActionMode)
                    _vm.ExitActionMode();
                else
                    Hide();
                e.Handled = true;
                break;

            case Key.Enter:
                // Ctrl+Enter, Alt+Enter → Window_KeyDown에서 처리
                if ((Keyboard.Modifiers & ModifierKeys.Control) != 0 ||
                    (Keyboard.Modifiers & ModifierKeys.Alt) != 0)
                    return;

                if (shift)
                {
                    // Phase L2-3: 클립보드 이미지 항목 → 이미지 미리보기 창 열기
                    if (_vm.SelectedItem?.Data is AxCopilot.Services.ClipboardEntry imgEntry && !imgEntry.IsText)
                    {
                        e.Handled = true;
                        Hide();
                        var previewWin = new ClipboardImagePreviewWindow(imgEntry);
                        previewWin.Show();
                        break;
                    }

                    // 퍼지 파일 검색 결과: Shift+Enter → 파일이 있는 폴더 열기
                    if (_vm.SelectedItem?.Data is AxCopilot.Services.IndexEntry shiftEntry)
                    {
                        var expanded = Environment.ExpandEnvironmentVariables(shiftEntry.Path);
                        Hide();
                        // File.Exists/Directory.Exists 생략 — 탐색기가 없는 경로는 알아서 처리
                        // 폴더인 경우 바로 열기, 파일인 경우 /select로 위치 표시
                        _ = Task.Run(() =>
                        {
                            try
                            {
                                if (shiftEntry.Type == Services.IndexEntryType.Folder)
                                    System.Diagnostics.Process.Start("explorer.exe", $"\"{expanded}\"");
                                else
                                    System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{expanded}\"");
                            }
                            catch (Exception) { }
                        });
                    }
                    // 캡처 모드: 지연 캡처 타이머 표시
                    else if (_vm.ActivePrefix != null &&
                        _vm.ActivePrefix.Equals("cap", StringComparison.OrdinalIgnoreCase) &&
                        _vm.ShowDelayTimerItems())
                    {
                        // 타이머 선택 목록으로 전환됨 — Enter로 선택
                    }
                    else if (_vm.MergeCount > 0)
                        _vm.ExecuteMerge();
                    else
                        ShowLargeType();
                }
                else if (_vm.IsActionMode && TryHandleSpecialAction())
                {
                    // 삭제/이름 변경 등 특수 액션 처리됨 — 별도 처리
                }
                else
                {
                    _ = _vm.ExecuteSelectedAsync();
                }
                e.Handled = true;
                break;

            case Key.Down:
                if (shift)
                {
                    _vm.ToggleMergeItem(_vm.SelectedItem);
                    _vm.SelectNext();
                }
                else if (_vm.Results.Count == 0)
                {
                    // 결과 없음 → 검색 히스토리 탐색 (최신 방향)
                    var histNext = _vm.NavigateHistoryNext();
                    if (histNext != null)
                    {
                        _vm.SetInputFromHistory(histNext);
                        InputBox.CaretIndex = InputBox.Text.Length;
                    }
                }
                else
                {
                    _vm.SelectNext();
                }
                ScrollToSelected();
                e.Handled = true;
                break;

            case Key.Up:
                if (shift)
                {
                    _vm.ToggleMergeItem(_vm.SelectedItem);
                    _vm.SelectPrev();
                }
                else if (_vm.Results.Count == 0)
                {
                    // 결과 없음 → 검색 히스토리 탐색 (이전 방향)
                    var histPrev = _vm.NavigateHistoryPrev();
                    if (histPrev != null)
                    {
                        _vm.SetInputFromHistory(histPrev);
                        InputBox.CaretIndex = InputBox.Text.Length;
                    }
                }
                else
                {
                    _vm.SelectPrev();
                }
                ScrollToSelected();
                e.Handled = true;
                break;

            case Key.Right:
                // 커서가 입력 끝에 있을 때
                if (InputBox.CaretIndex == InputBox.Text.Length && InputBox.Text.Length > 0)
                {
                    // 파일 탐색기: 선택된 항목이 폴더이면 해당 경로로 진입
                    if (_vm.SelectedItem?.Data is AxCopilot.Handlers.FileBrowserEntry { IsFolder: true } fb)
                    {
                        _vm.InputText = fb.Path.TrimEnd('\\', '/') + "\\";
                        Dispatcher.BeginInvoke(() =>
                        {
                            InputBox.CaretIndex = InputBox.Text.Length;
                        }, System.Windows.Threading.DispatcherPriority.Input);
                        e.Handled = true;
                    }
                    // 일반 항목: 액션 서브메뉴 진입
                    else if (_vm.CanEnterActionMode())
                    {
                        _vm.EnterActionMode(_vm.SelectedItem!);
                        e.Handled = true;
                    }
                }
                break;

            case Key.Left:
                // 파일 탐색기 모드에서 커서가 끝에 있고 입력이 경로이면 상위 폴더로 이동
                if (InputBox.CaretIndex == InputBox.Text.Length
                    && AxCopilot.Handlers.FileBrowserHandler.IsPathQuery(InputBox.Text))
                {
                    var trimmed = InputBox.Text.TrimEnd('\\', '/');
                    var parent = System.IO.Path.GetDirectoryName(trimmed);
                    if (!string.IsNullOrEmpty(parent))
                    {
                        _vm.InputText = parent.TrimEnd('\\', '/') + "\\";
                        Dispatcher.BeginInvoke(() =>
                        {
                            InputBox.CaretIndex = InputBox.Text.Length;
                        }, System.Windows.Threading.DispatcherPriority.Input);
                        e.Handled = true;
                    }
                }
                break;

            case Key.PageDown:
                for (int i = 0; i < 5 && _vm.Results.Count > 0; i++) _vm.SelectNext();
                ScrollToSelected();
                e.Handled = true;
                break;

            case Key.PageUp:
                for (int i = 0; i < 5 && _vm.Results.Count > 0; i++) _vm.SelectPrev();
                ScrollToSelected();
                e.Handled = true;
                break;

            case Key.Home:
                // 입력창 커서가 맨 앞이거나 입력이 없을 때 → 목록 첫 항목으로 이동
                if (InputBox.CaretIndex == 0 || string.IsNullOrEmpty(InputBox.Text))
                {
                    _vm.SelectFirst();
                    ScrollToSelected();
                    e.Handled = true;
                }
                break;

            case Key.End:
                // 입력창 커서가 맨 끝이거나 입력이 없을 때 → 목록 마지막 항목으로 이동
                if (InputBox.CaretIndex == InputBox.Text.Length || string.IsNullOrEmpty(InputBox.Text))
                {
                    _vm.SelectLast();
                    ScrollToSelected();
                    e.Handled = true;
                }
                break;

            case Key.Tab:
                // 자동완성: 선택된 항목의 Title을 입력창에 채우고 커서를 끝으로 이동
                if (_vm.SelectedItem != null)
                {
                    _vm.InputText = _vm.SelectedItem.Title;
                    // 바인딩 업데이트 후 커서를 끝으로 — Dispatcher로 다음 렌더 사이클에 실행
                    Dispatcher.BeginInvoke(() =>
                    {
                        InputBox.CaretIndex = InputBox.Text.Length;
                        InputBox.Focus();
                    }, System.Windows.Threading.DispatcherPriority.Input);
                }
                e.Handled = true;
                break;
        }
    }

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        var mod = Keyboard.Modifiers;

        // ─── Ctrl+, → 설정 창 열기 ─────────────────────────────────────────
        if (e.Key == Key.OemComma && mod == ModifierKeys.Control)
        {
            Hide();
            OpenSettingsAction?.Invoke();
            e.Handled = true;
            return;
        }

        // ─── F1 → 도움말 창 열기 ────────────────────────────────────────────
        if (e.Key == Key.F1)
        {
            _vm.InputText = "help";
            e.Handled = true;
            return;
        }

        // ─── F5 → 인덱스 새로 고침 ──────────────────────────────────────────
        if (e.Key == Key.F5)
        {
            var app = (App)System.Windows.Application.Current;
            _ = app.IndexService?.BuildAsync(CancellationToken.None);
            IndexStatusText.Text = "⟳ 인덱스 재구축 중…";
            IndexStatusText.Visibility = Visibility.Visible;
            e.Handled = true;
            return;
        }

        // ─── Delete → 항목 삭제 ─────────────────────────────────────────────
        if (e.Key == Key.Delete && mod == ModifierKeys.None)
        {
            if (_vm.SelectedItem != null)
            {
                var input = _vm.InputText ?? "";
                // note 예약어 활성 상태에서 메모 개별 삭제
                if (input.StartsWith("note", StringComparison.OrdinalIgnoreCase)
                    && _vm.SelectedItem.Data is string noteContent
                    && noteContent != "__CLEAR__")
                {
                    var title = _vm.SelectedItem.Title;
                    var result = CustomMessageBox.Show(
                        $"'{title}' 메모를 삭제하시겠습니까?",
                        "AX Copilot",
                        MessageBoxButton.OKCancel,
                        MessageBoxImage.Question);

                    if (result == MessageBoxResult.OK)
                    {
                        Handlers.NoteHandler.DeleteNote(noteContent);
                        // 결과 목록 새로고침 (InputText 재설정으로 SearchAsync 트리거)
                        var current = _vm.InputText ?? "";
                        _vm.InputText = current + " ";
                        _vm.InputText = current;
                    }
                }
                else
                {
                    var title = _vm.SelectedItem.Title;
                    var result = CustomMessageBox.Show(
                        $"'{title}' 항목을 목록에서 제거하시겠습니까?",
                        "AX Copilot",
                        MessageBoxButton.OKCancel,
                        MessageBoxImage.Question);

                    if (result == MessageBoxResult.OK)
                        _vm.RemoveSelectedFromRecent();
                }
            }
            e.Handled = true;
            return;
        }

        // ─── Ctrl+L → 입력창 초기화 ─────────────────────────────────────────
        if (e.Key == Key.L && mod == ModifierKeys.Control)
        {
            _vm.ClearInput();
            InputBox.Focus();
            e.Handled = true;
            return;
        }

        // ─── Ctrl+C → 선택 항목 이름 복사 (결과 선택 시) ────────────────────
        if (e.Key == Key.C && mod == ModifierKeys.Control && _vm.SelectedItem?.Data is AxCopilot.Services.IndexEntry)
        {
            _vm.CopySelectedPath();
            ShowToast("이름 복사됨");
            e.Handled = true;
            return;
        }

        // ─── Ctrl+Shift+C → 전체 경로 복사 ──────────────────────────────────
        if (e.Key == Key.C && mod == (ModifierKeys.Control | ModifierKeys.Shift))
        {
            if (_vm.CopySelectedFullPath())
                ShowToast("경로 복사됨");
            e.Handled = true;
            return;
        }

        // ─── Ctrl+Shift+E → 파일 탐색기에서 열기 ────────────────────────────
        if (e.Key == Key.E && mod == (ModifierKeys.Control | ModifierKeys.Shift))
        {
            if (_vm.OpenSelectedInExplorer())
                Hide();
            e.Handled = true;
            return;
        }

        // ─── Ctrl+Enter → 관리자 권한 실행 ──────────────────────────────────
        if (e.Key == Key.Enter && mod == ModifierKeys.Control)
        {
            if (_vm.RunSelectedAsAdmin())
                Hide();
            e.Handled = true;
            return;
        }

        // ─── Alt+Enter → 파일 속성 보기 ─────────────────────────────────────
        if (e.Key == Key.Enter && mod == ModifierKeys.Alt)
        {
            _vm.ShowSelectedProperties();
            e.Handled = true;
            return;
        }

        // ─── Ctrl+H → 클립보드 히스토리 ─────────────────────────────────────
        if (e.Key == Key.H && mod == ModifierKeys.Control)
        {
            _vm.InputText = "#";
            Dispatcher.BeginInvoke(() => { InputBox.CaretIndex = InputBox.Text.Length; },
                System.Windows.Threading.DispatcherPriority.Input);
            e.Handled = true;
            return;
        }

        // ─── Ctrl+R → 최근 실행 항목 ────────────────────────────────────────
        if (e.Key == Key.R && mod == ModifierKeys.Control)
        {
            _vm.InputText = "recent";
            Dispatcher.BeginInvoke(() => { InputBox.CaretIndex = InputBox.Text.Length; },
                System.Windows.Threading.DispatcherPriority.Input);
            e.Handled = true;
            return;
        }

        // ─── Ctrl+B → 즐겨찾기 뷰 토글 (fav 이면 이전 검색으로, 아니면 fav로) ─
        if (e.Key == Key.B && mod == ModifierKeys.Control)
        {
            if (_vm.InputText.TrimStart().Equals("fav", StringComparison.OrdinalIgnoreCase))
                _vm.ClearInput();
            else
                _vm.InputText = "fav";
            Dispatcher.BeginInvoke(() => { InputBox.CaretIndex = InputBox.Text.Length; },
                System.Windows.Threading.DispatcherPriority.Input);
            e.Handled = true;
            return;
        }

        // ─── Ctrl+K → 단축키 도움말 모달 창 ─────────────────────────────────
        if (e.Key == Key.K && mod == ModifierKeys.Control)
        {
            var helpWin = new ShortcutHelpWindow { Owner = this };
            helpWin.ShowDialog();
            e.Handled = true;
            return;
        }

        // ─── Ctrl+T → 터미널 열기 (선택 항목 경로, 없으면 홈) ────────────────
        if (e.Key == Key.T && mod == ModifierKeys.Control)
        {
            _vm.OpenSelectedInTerminal();
            Hide();
            e.Handled = true;
            return;
        }

        // ─── Ctrl+F → 파일 검색 모드 전환 ───────────────────────────────────
        if (e.Key == Key.F && mod == ModifierKeys.Control)
        {
            // 입력창 초기화 후 파일 타입 필터 힌트
            _vm.ClearInput();
            Dispatcher.BeginInvoke(() =>
            {
                InputBox.Focus();
                InputBox.CaretIndex = InputBox.Text.Length;
            }, System.Windows.Threading.DispatcherPriority.Input);
            e.Handled = true;
            return;
        }

        // ─── Ctrl+P → 클립보드 모드에서 핀 토글 / 일반 모드에서 즐겨찾기 ───
        if (e.Key == Key.P && mod == ModifierKeys.Control)
        {
            if (_vm.IsClipboardMode && _vm.SelectedItem?.Data is Services.ClipboardEntry clipEntry)
            {
                var clipSvc = CurrentApp?.ClipboardHistoryService;
                clipSvc?.TogglePin(clipEntry);
                ShowToast(clipEntry.IsPinned ? "클립보드 핀 고정 📌" : "클립보드 핀 해제");
                // 검색 결과 갱신
                _vm.InputText = _vm.InputText;
            }
            else
            {
                var result = _vm.ToggleFavorite();
                if (result == true)
                    ShowToast("즐겨찾기에 추가됨  ⭐");
                else if (result == false)
                    ShowToast("즐겨찾기에서 제거됨");
                else
                    ShowToast("파일/폴더 항목을 선택하세요");
            }
            e.Handled = true;
            return;
        }

        // ─── Ctrl+D → 다운로드 폴더 열기 ───────────────────────────────────
        if (e.Key == Key.D && mod == ModifierKeys.Control)
        {
            _vm.NavigateToDownloads();
            Dispatcher.BeginInvoke(() => { InputBox.CaretIndex = InputBox.Text.Length; },
                System.Windows.Threading.DispatcherPriority.Input);
            e.Handled = true;
            return;
        }

        // ─── Ctrl+W → 런처 창 닫기 ──────────────────────────────────────────
        if (e.Key == Key.W && mod == ModifierKeys.Control)
        {
            Hide();
            e.Handled = true;
            return;
        }

        // ─── F2 → 선택 파일 이름 바꾸기 ─────────────────────────────────────
        if (e.Key == Key.F2)
        {
            if (_vm.SelectedItem?.Data is AxCopilot.Services.IndexEntry entry)
            {
                var path = Environment.ExpandEnvironmentVariables(entry.Path);
                _vm.InputText = $"rename {path}";
                Dispatcher.BeginInvoke(() => { InputBox.CaretIndex = InputBox.Text.Length; },
                    System.Windows.Threading.DispatcherPriority.Input);
            }
            e.Handled = true;
            return;
        }

        // ─── F3 → 파일 빠른 미리보기 (QuickLook 토글) ────────────────────────
        if (e.Key == Key.F3)
        {
            ToggleQuickLook();
            e.Handled = true;
            return;
        }

        // ─── F4 → 화면 영역 OCR 즉시 실행 ──────────────────────────────────
        if (e.Key == Key.F4)
        {
            Hide();
            _ = Task.Run(async () =>
            {
                try
                {
                    var handler = new Handlers.OcrHandler();
                    var item = new SDK.LauncherItem(
                        "화면 영역 텍스트 추출", "", null, "__ocr_region__");
                    await handler.ExecuteAsync(item, CancellationToken.None);
                }
                catch (Exception ex)
                {
                    Services.LogService.Error($"F4 OCR 실행 오류: {ex.Message}");
                }
            });
            e.Handled = true;
            return;
        }

        // ─── Ctrl+1~9 → n번째 결과 즉시 실행 ───────────────────────────────
        if (mod == ModifierKeys.Control)
        {
            int num = e.Key switch
            {
                Key.D1 => 1, Key.D2 => 2, Key.D3 => 3,
                Key.D4 => 4, Key.D5 => 5, Key.D6 => 6,
                Key.D7 => 7, Key.D8 => 8, Key.D9 => 9,
                _ => 0
            };
            if (num > 0 && num <= _vm.Results.Count)
            {
                _vm.SelectedItem = _vm.Results[num - 1];
                _ = _vm.ExecuteSelectedAsync();
                Hide();
                e.Handled = true;
                return;
            }
        }
    }
}
