using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using AxCopilot.Models;
using AxCopilot.Services;

namespace AxCopilot.Views;

public partial class ChatWindow
{
    // ─── 작업 폴더 ─────────────────────────────────────────────────────────

    private readonly List<string> _attachedFiles = new();
    private readonly List<ImageAttachment> _pendingImages = new();

    private void FolderPathLabel_Click(object sender, MouseButtonEventArgs e) => ShowFolderMenu();

    private void ShowFolderMenu()
    {
        FolderMenuItems.Children.Clear();

        var accentBrush = ThemeResourceHelper.Accent(this);
        var primaryText = ThemeResourceHelper.Primary(this);
        var secondaryText = ThemeResourceHelper.Secondary(this);

        // 최근 폴더 목록
        var maxDisplay = Math.Clamp(Llm.MaxRecentFolders, 3, 30);
        var recentFolders = Llm.RecentWorkFolders
            .Where(p => IsPathAllowed(p) && System.IO.Directory.Exists(p))
            .Take(maxDisplay)
            .ToList();

        if (recentFolders.Count > 0)
        {
            FolderMenuItems.Children.Add(new TextBlock
            {
                Text = "최근 폴더",
                FontSize = 12.5,
                FontWeight = FontWeights.SemiBold,
                Foreground = secondaryText,
                Margin = new Thickness(10, 6, 10, 4),
            });

            var currentFolder = GetCurrentWorkFolder();
            foreach (var folder in recentFolders)
            {
                var isActive = folder.Equals(currentFolder, StringComparison.OrdinalIgnoreCase);
                var displayName = System.IO.Path.GetFileName(folder);
                if (string.IsNullOrEmpty(displayName)) displayName = folder;

                var sp = new StackPanel { Orientation = Orientation.Horizontal };
                if (isActive)
                {
                    var checkEl = CreateSimpleCheck(accentBrush, 14);
                    checkEl.Margin = new Thickness(0, 0, 8, 0);
                    sp.Children.Add(checkEl);
                }
                var nameBlock = new TextBlock
                {
                    Text = displayName,
                    FontSize = 14,
                    FontWeight = isActive ? FontWeights.SemiBold : FontWeights.Normal,
                    Foreground = primaryText,
                    VerticalAlignment = VerticalAlignment.Center,
                    MaxWidth = 340,
                    TextTrimming = TextTrimming.CharacterEllipsis,
                };
                sp.Children.Add(nameBlock);

                var itemBorder = new Border
                {
                    Child = sp,
                    Background = Brushes.Transparent,
                    CornerRadius = new CornerRadius(8),
                    Cursor = Cursors.Hand,
                    Padding = new Thickness(10, 7, 10, 7),
                    ToolTip = folder,
                };
                itemBorder.MouseEnter += (s, _) => { if (s is Border b) b.Background = new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF)); };
                itemBorder.MouseLeave += (s, _) => { if (s is Border b) b.Background = Brushes.Transparent; };
                var capturedPath = folder;
                itemBorder.MouseLeftButtonUp += (_, _) =>
                {
                    FolderMenuPopup.IsOpen = false;
                    SetWorkFolder(capturedPath);
                };
                // 우클릭 → 컨텍스트 메뉴 (삭제, 폴더 열기)
                itemBorder.MouseRightButtonUp += (_, re) =>
                {
                    re.Handled = true;
                    ShowRecentFolderContextMenu(capturedPath);
                };
                FolderMenuItems.Children.Add(itemBorder);
            }

            // 구분선
            FolderMenuItems.Children.Add(new Border
            {
                Height = 1,
                Background = ThemeResourceHelper.Border(this),
                Margin = new Thickness(8, 4, 8, 4),
                Opacity = 0.5,
            });
        }

        // 폴더 찾아보기 버튼
        var browseSp = new StackPanel { Orientation = Orientation.Horizontal };
        browseSp.Children.Add(new TextBlock
        {
            Text = "\uED25",
            FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize = 14,
            Foreground = accentBrush,
            VerticalAlignment = VerticalAlignment.Center,
            Margin = new Thickness(0, 0, 8, 0),
        });
        browseSp.Children.Add(new TextBlock
        {
            Text = "폴더 찾아보기...",
            FontSize = 14,
            Foreground = primaryText,
            VerticalAlignment = VerticalAlignment.Center,
        });
        var browseBorder = new Border
        {
            Child = browseSp,
            Background = Brushes.Transparent,
            CornerRadius = new CornerRadius(8),
            Cursor = Cursors.Hand,
            Padding = new Thickness(10, 7, 10, 7),
        };
        browseBorder.MouseEnter += (s, _) => { if (s is Border b) b.Background = new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF)); };
        browseBorder.MouseLeave += (s, _) => { if (s is Border b) b.Background = Brushes.Transparent; };
        browseBorder.MouseLeftButtonUp += (_, _) =>
        {
            FolderMenuPopup.IsOpen = false;
            BrowseWorkFolder();
        };
        FolderMenuItems.Children.Add(browseBorder);

        FolderMenuPopup.IsOpen = true;
    }

    private void BrowseWorkFolder()
    {
        var dlg = new System.Windows.Forms.FolderBrowserDialog
        {
            Description = "작업 폴더를 선택하세요",
            ShowNewFolderButton = false,
            UseDescriptionForTitle = true,
        };

        var currentFolder = GetCurrentWorkFolder();
        if (!string.IsNullOrEmpty(currentFolder) && System.IO.Directory.Exists(currentFolder))
            dlg.SelectedPath = currentFolder;

        if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;

        if (!IsPathAllowed(dlg.SelectedPath))
        {
            CustomMessageBox.Show("이 경로는 작업 폴더로 선택할 수 없습니다.", "경로 제한", MessageBoxButton.OK, MessageBoxImage.Warning);
            return;
        }

        SetWorkFolder(dlg.SelectedPath);
    }

    /// <summary>경로 유효성 검사 — 차단 대상 경로 필터링.</summary>
    private static bool IsPathAllowed(string path)
    {
        if (string.IsNullOrWhiteSpace(path)) return false;
        // C:\ 루트 차단
        var normalized = path.TrimEnd('\\', '/');
        if (normalized.Equals("C:", StringComparison.OrdinalIgnoreCase)) return false;
        // "Document" 포함 경로 차단 (대소문자 무시)
        if (path.IndexOf("Document", StringComparison.OrdinalIgnoreCase) >= 0) return false;
        return true;
    }

    private void SetWorkFolder(string path)
    {
        // 루트 드라이브 전체를 작업공간으로 설정하는 것을 차단
        // 예: "C:\", "D:\", "E:\" 등
        var fullPath = System.IO.Path.GetFullPath(path);
        var root = System.IO.Path.GetPathRoot(fullPath);
        if (!string.IsNullOrEmpty(root) && fullPath.TrimEnd('\\', '/').Equals(root.TrimEnd('\\', '/'), StringComparison.OrdinalIgnoreCase))
        {
            ShowToast($"드라이브 루트({root})는 작업공간으로 설정할 수 없습니다. 하위 폴더를 선택하세요.", "\uE783", 3000);
            return;
        }

        FolderPathLabel.Text = path;
        FolderPathLabel.ToolTip = path;

        lock (_convLock)
        {
            if (_currentConversation != null)
                _currentConversation.WorkFolder = path;
        }

        // 최근 폴더 목록에 추가 (차단 경로 제외)
        var recent = Llm.RecentWorkFolders;
        recent.RemoveAll(p => !IsPathAllowed(p));
        recent.Remove(path);
        recent.Insert(0, path);
        var maxRecent = Math.Clamp(Llm.MaxRecentFolders, 3, 30);
        if (recent.Count > maxRecent) recent.RemoveRange(maxRecent, recent.Count - maxRecent);
        Llm.WorkFolder = path;
        _settings.Save();

        // Phase 17-C: CwdChanged 훅 발화 (fire-and-forget)
        _ = _agentLoop.RunExtendedEventAsync(
            Services.Agent.HookEventKind.CwdChanged,
            null,
            CancellationToken.None,
            toolInput: path);
    }

    private string GetCurrentWorkFolder()
    {
        lock (_convLock)
        {
            if (_currentConversation != null && !string.IsNullOrEmpty(_currentConversation.WorkFolder))
                return _currentConversation.WorkFolder;
        }
        return Llm.WorkFolder;
    }

    /// <summary>테마에 맞는 ContextMenu를 생성합니다.</summary>
    private ContextMenu CreateThemedContextMenu()
    {
        var bg = ThemeResourceHelper.Background(this);
        var border = ThemeResourceHelper.Border(this);
        return new ContextMenu
        {
            Background = bg,
            BorderBrush = border,
            BorderThickness = new Thickness(1),
            Padding = new Thickness(4),
        };
    }

    /// <summary>최근 폴더 항목 우클릭 컨텍스트 메뉴를 표시합니다.</summary>
    private void ShowRecentFolderContextMenu(string folderPath)
    {
        var menu = CreateThemedContextMenu();
        var primaryText = ThemeResourceHelper.Primary(this);
        var secondaryText = ThemeResourceHelper.Secondary(this);

        void AddItem(string icon, string label, Action action)
        {
            var sp = new StackPanel { Orientation = Orientation.Horizontal };
            sp.Children.Add(new TextBlock
            {
                Text = icon, FontFamily = ThemeResourceHelper.SegoeMdl2,
                FontSize = 12, Foreground = secondaryText,
                VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 0, 8, 0),
            });
            sp.Children.Add(new TextBlock
            {
                Text = label, FontSize = 12, Foreground = primaryText,
                VerticalAlignment = VerticalAlignment.Center,
            });
            var mi = new MenuItem { Header = sp, Padding = new Thickness(8, 6, 16, 6) };
            mi.Click += (_, _) => action();
            menu.Items.Add(mi);
        }

        AddItem("\uED25", "폴더 열기", () =>
        {
            try
            {
                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
                {
                    FileName = folderPath,
                    UseShellExecute = true,
                });
            }
            catch (Exception) { /* 비핵심 작업 실패 — UI 차단 방지 */ }
        });

        AddItem("\uE8C8", "경로 복사", () =>
        {
            try { Clipboard.SetText(folderPath); } catch (Exception) { /* 클립보드 접근 실패 */ }
        });

        menu.Items.Add(new Separator());

        AddItem("\uE74D", "목록에서 삭제", () =>
        {
            Llm.RecentWorkFolders.RemoveAll(
                p => p.Equals(folderPath, StringComparison.OrdinalIgnoreCase));
            _settings.Save();
            // 메뉴 새로고침
            if (FolderMenuPopup.IsOpen)
                ShowFolderMenu();
        });

        menu.IsOpen = true;
    }

    private void BtnFolderClear_Click(object sender, RoutedEventArgs e)
    {
        FolderPathLabel.Text = "폴더를 선택하세요";
        FolderPathLabel.ToolTip = null;
        lock (_convLock)
        {
            if (_currentConversation != null)
                _currentConversation.WorkFolder = "";
        }
    }

    private void UpdateFolderBar()
    {
        if (FolderBar == null) return;
        if (_activeTab == "Chat")
        {
            FolderBar.Visibility = Visibility.Collapsed;
            return;
        }
        FolderBar.Visibility = Visibility.Visible;
        var folder = GetCurrentWorkFolder();
        if (!string.IsNullOrEmpty(folder))
        {
            FolderPathLabel.Text = folder;
            FolderPathLabel.ToolTip = folder;
        }
        else
        {
            FolderPathLabel.Text = "폴더를 선택하세요";
            FolderPathLabel.ToolTip = null;
        }
        // 대화별 설정 복원 (없으면 전역 기본값)
        LoadConversationSettings();
        UpdatePermissionUI();
        UpdateDataUsageUI();
    }

    /// <summary>현재 대화의 개별 설정을 로드합니다. null이면 전역 기본값 사용.</summary>
    private void LoadConversationSettings()
    {
        ChatConversation? conv;
        lock (_convLock) conv = _currentConversation;
        var llm = Llm;

        if (conv != null && conv.Permission != null)
            Llm.FilePermission = conv.Permission;

        _folderDataUsage = conv?.DataUsage ?? llm.FolderDataUsage ?? "active";
        _selectedMood = conv?.Mood ?? llm.DefaultMood ?? "modern";
    }

    /// <summary>현재 하단 바 설정을 대화에 저장합니다.</summary>
    private void SaveConversationSettings()
    {
        ChatConversation? conv;
        lock (_convLock) conv = _currentConversation;
        if (conv == null) return;

        conv.Permission = Llm.FilePermission;
        conv.DataUsage = _folderDataUsage;
        conv.Mood = _selectedMood;
        try { _storage.Save(conv); } catch (Exception ex) { Services.LogService.Debug($"대화 저장 실패: {ex.Message}"); }
    }
}
