using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using AxCopilot.Services.Agent;

namespace AxCopilot.Views;

public partial class ChatWindow
{
    // ─── 미리보기 패널 (탭 기반) ─────────────────────────────────────────────

    private static readonly HashSet<string> _previewableExtensions = new(StringComparer.OrdinalIgnoreCase)
    {
        ".html", ".htm", ".md", ".txt", ".csv", ".json", ".xml", ".log",
    };

    /// <summary>열려 있는 프리뷰 탭 목록 (파일 경로 기준).</summary>
    private readonly List<string> _previewTabs = new();
    private string? _activePreviewTab;

    private void TryShowPreview(string filePath)
    {
        if (string.IsNullOrEmpty(filePath) || !System.IO.File.Exists(filePath))
            return;

        // 별도 커스텀 창으로 미리보기 (WebView2 HWND airspace 문제 근본 해결)
        PreviewWindow.ShowPreview(filePath, _selectedMood);
    }

    private void ShowPreviewPanel(string filePath)
    {
        // 탭에 없으면 추가
        if (!_previewTabs.Contains(filePath, StringComparer.OrdinalIgnoreCase))
            _previewTabs.Add(filePath);

        _activePreviewTab = filePath;

        // 패널 열기
        if (PreviewColumn.Width.Value < 100)
        {
            PreviewColumn.Width = new GridLength(420);
            SplitterColumn.Width = new GridLength(5);
        }
        PreviewPanel.Visibility = Visibility.Visible;
        PreviewSplitter.Visibility = Visibility.Visible;
        BtnPreviewToggle.Visibility = Visibility.Visible;

        RebuildPreviewTabs();
        LoadPreviewContent(filePath);
    }

    /// <summary>탭 바 UI를 다시 구성합니다.</summary>
    private void RebuildPreviewTabs()
    {
        PreviewTabPanel.Children.Clear();

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

        foreach (var tabPath in _previewTabs)
        {
            var fileName = System.IO.Path.GetFileName(tabPath);
            var isActive = string.Equals(tabPath, _activePreviewTab, StringComparison.OrdinalIgnoreCase);

            var tabBorder = new Border
            {
                Background = isActive
                    ? new SolidColorBrush(Color.FromArgb(0x15, 0xFF, 0xFF, 0xFF))
                    : Brushes.Transparent,
                BorderBrush = isActive ? accentBrush : Brushes.Transparent,
                BorderThickness = new Thickness(0, 0, 0, isActive ? 2 : 0),
                Padding = new Thickness(8, 6, 4, 6),
                Cursor = Cursors.Hand,
                MaxWidth = _previewTabs.Count <= 3 ? 200 : (_previewTabs.Count <= 5 ? 140 : 100),
            };

            var tabContent = new StackPanel { Orientation = Orientation.Horizontal };

            // 파일명
            tabContent.Children.Add(new TextBlock
            {
                Text = fileName,
                FontSize = 11,
                Foreground = isActive ? primaryText : secondaryText,
                FontWeight = isActive ? FontWeights.SemiBold : FontWeights.Normal,
                VerticalAlignment = VerticalAlignment.Center,
                TextTrimming = TextTrimming.CharacterEllipsis,
                MaxWidth = tabBorder.MaxWidth - 30,
                ToolTip = tabPath,
            });

            // 닫기 버튼 (x) — 활성 탭은 항상 표시, 비활성 탭은 호버 시에만 표시
            var closeFg = isActive ? primaryText : secondaryText;
            var closeBtnText = new TextBlock
            {
                Text = "\uE711",
                FontFamily = ThemeResourceHelper.SegoeMdl2,
                FontSize = 10,
                Foreground = closeFg,
                VerticalAlignment = VerticalAlignment.Center,
            };
            var closeBtn = new Border
            {
                Background = Brushes.Transparent,
                CornerRadius = new CornerRadius(3),
                Padding = new Thickness(3, 2, 3, 2),
                Margin = new Thickness(5, 0, 0, 0),
                Cursor = Cursors.Hand,
                VerticalAlignment = VerticalAlignment.Center,
                // 비활성 탭은 초기에 숨김, 활성 탭은 항상 표시
                Visibility = isActive ? Visibility.Visible : Visibility.Hidden,
                Child = closeBtnText,
            };

            var closePath = tabPath;
            closeBtn.MouseEnter += (s, _) =>
            {
                if (s is Border b)
                {
                    b.Background = new SolidColorBrush(Color.FromArgb(0x40, 0xFF, 0x50, 0x50));
                    if (b.Child is TextBlock tb) tb.Foreground = new SolidColorBrush(Color.FromRgb(0xFF, 0x60, 0x60));
                }
            };
            closeBtn.MouseLeave += (s, _) =>
            {
                if (s is Border b)
                {
                    b.Background = Brushes.Transparent;
                    if (b.Child is TextBlock tb) tb.Foreground = closeFg;
                }
            };
            closeBtn.Tag = "close"; // 닫기 버튼 식별용
            closeBtn.MouseLeftButtonUp += (_, e) =>
            {
                e.Handled = true; // 부모 탭 클릭 이벤트 차단
                ClosePreviewTab(closePath);
            };

            tabContent.Children.Add(closeBtn);
            tabBorder.Child = tabContent;

            // 탭 클릭 → 활성화 (MouseLeftButtonUp 사용: 닫기 버튼의 PreviewMouseLeftButtonDown보다 늦게 실행되어 충돌 방지)
            var clickPath = tabPath;
            tabBorder.MouseLeftButtonUp += (_, e) =>
            {
                if (e.Handled) return;
                e.Handled = true;
                _activePreviewTab = clickPath;
                RebuildPreviewTabs();
                LoadPreviewContent(clickPath);
            };

            // 우클릭 → 컨텍스트 메뉴
            var ctxPath = tabPath;
            tabBorder.MouseRightButtonUp += (_, e) =>
            {
                e.Handled = true;
                ShowPreviewTabContextMenu(ctxPath);
            };

            // 더블클릭 → 별도 창에서 보기
            var dblPath = tabPath;
            tabBorder.MouseLeftButtonDown += (_, e) =>
            {
                if (e.Handled) return;
                if (e.ClickCount == 2)
                {
                    e.Handled = true;
                    OpenPreviewPopupWindow(dblPath);
                }
            };

            // 호버 효과 — 비활성 탭에서 배경 강조 + 닫기 버튼 표시
            var capturedIsActive = isActive;
            var capturedCloseBtn = closeBtn;
            tabBorder.MouseEnter += (s, _) =>
            {
                if (s is Border b && !capturedIsActive)
                    b.Background = new SolidColorBrush(Color.FromArgb(0x10, 0xFF, 0xFF, 0xFF));
                // 비활성 탭도 호버 시 닫기 버튼 표시
                if (!capturedIsActive)
                    capturedCloseBtn.Visibility = Visibility.Visible;
            };
            tabBorder.MouseLeave += (s, _) =>
            {
                if (s is Border b && !capturedIsActive)
                    b.Background = Brushes.Transparent;
                // 비활성 탭 호버 해제 시 닫기 버튼 숨김
                if (!capturedIsActive)
                    capturedCloseBtn.Visibility = Visibility.Hidden;
            };

            PreviewTabPanel.Children.Add(tabBorder);

            // 탭 사이 구분선
            if (tabPath != _previewTabs[^1])
            {
                PreviewTabPanel.Children.Add(new Border
                {
                    Width = 1, Height = 14,
                    Background = borderBrush,
                    Margin = new Thickness(0, 4, 0, 4),
                    VerticalAlignment = VerticalAlignment.Center,
                });
            }
        }
    }

    private void ClosePreviewTab(string filePath)
    {
        _previewTabs.Remove(filePath);

        if (_previewTabs.Count == 0)
        {
            HidePreviewPanel();
            return;
        }

        // 닫힌 탭이 활성 탭이면 마지막 탭으로 전환
        if (string.Equals(filePath, _activePreviewTab, StringComparison.OrdinalIgnoreCase))
        {
            _activePreviewTab = _previewTabs[^1];
            LoadPreviewContent(_activePreviewTab);
        }

        RebuildPreviewTabs();
    }

    private async void LoadPreviewContent(string filePath)
    {
        var ext = System.IO.Path.GetExtension(filePath).ToLowerInvariant();

        // 모든 콘텐츠 숨기기
        PreviewWebView.Visibility = Visibility.Collapsed;
        PreviewTextScroll.Visibility = Visibility.Collapsed;
        PreviewDataGrid.Visibility = Visibility.Collapsed;
        PreviewEmpty.Visibility = Visibility.Collapsed;

        if (!System.IO.File.Exists(filePath))
        {
            PreviewEmpty.Text = "파일을 찾을 수 없습니다";
            PreviewEmpty.Visibility = Visibility.Visible;
            return;
        }

        try
        {
            switch (ext)
            {
                case ".html":
                case ".htm":
                    await EnsureWebViewInitializedAsync();
                    PreviewWebView.Source = new Uri(filePath);
                    PreviewWebView.Visibility = Visibility.Visible;
                    break;

                case ".csv":
                    LoadCsvPreview(filePath);
                    PreviewDataGrid.Visibility = Visibility.Visible;
                    break;

                case ".md":
                    await EnsureWebViewInitializedAsync();
                    var mdText = System.IO.File.ReadAllText(filePath);
                    if (mdText.Length > 50000) mdText = mdText[..50000];
                    var mdHtml = Services.Agent.TemplateService.RenderMarkdownToHtml(mdText, _selectedMood);
                    PreviewWebView.NavigateToString(mdHtml);
                    PreviewWebView.Visibility = Visibility.Visible;
                    break;

                case ".txt":
                case ".json":
                case ".xml":
                case ".log":
                    var text = System.IO.File.ReadAllText(filePath);
                    if (text.Length > 50000) text = text[..50000] + "\n\n... (이후 생략)";
                    PreviewTextBlock.Text = text;
                    PreviewTextScroll.Visibility = Visibility.Visible;
                    break;

                default:
                    PreviewEmpty.Text = "미리보기할 수 없는 파일 형식입니다";
                    PreviewEmpty.Visibility = Visibility.Visible;
                    break;
            }
        }
        catch (Exception ex)
        {
            PreviewTextBlock.Text = $"미리보기 오류: {ex.Message}";
            PreviewTextScroll.Visibility = Visibility.Visible;
        }
    }

    private bool _webViewInitialized;
    private static readonly string WebView2DataFolder =
        System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                               "AxCopilot", "WebView2");

    private async Task EnsureWebViewInitializedAsync()
    {
        if (_webViewInitialized) return;
        try
        {
            var env = await Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateAsync(
                userDataFolder: WebView2DataFolder);
            await PreviewWebView.EnsureCoreWebView2Async(env);
            _webViewInitialized = true;
        }
        catch (Exception ex)
        {
            Services.LogService.Warn($"WebView2 초기화 실패: {ex.Message}");
        }
    }

    private void LoadCsvPreview(string filePath)
    {
        try
        {
            var lines = System.IO.File.ReadAllLines(filePath);
            if (lines.Length == 0) return;

            var dt = new System.Data.DataTable();
            var headers = ParseCsvLine(lines[0]);
            foreach (var h in headers)
                dt.Columns.Add(h);

            var maxRows = Math.Min(lines.Length, 501);
            for (int i = 1; i < maxRows; i++)
            {
                var vals = ParseCsvLine(lines[i]);
                var row = dt.NewRow();
                for (int j = 0; j < Math.Min(vals.Length, headers.Length); j++)
                    row[j] = vals[j];
                dt.Rows.Add(row);
            }

            PreviewDataGrid.ItemsSource = dt.DefaultView;
        }
        catch (Exception ex)
        {
            PreviewTextBlock.Text = $"CSV 로드 오류: {ex.Message}";
            PreviewTextScroll.Visibility = Visibility.Visible;
            PreviewDataGrid.Visibility = Visibility.Collapsed;
        }
    }

    private static string[] ParseCsvLine(string line)
    {
        var fields = new System.Collections.Generic.List<string>();
        var current = new System.Text.StringBuilder();
        bool inQuotes = false;

        for (int i = 0; i < line.Length; i++)
        {
            char c = line[i];
            if (inQuotes)
            {
                if (c == '"' && i + 1 < line.Length && line[i + 1] == '"')
                {
                    current.Append('"');
                    i++;
                }
                else if (c == '"')
                    inQuotes = false;
                else
                    current.Append(c);
            }
            else
            {
                if (c == '"')
                    inQuotes = true;
                else if (c == ',')
                {
                    fields.Add(current.ToString());
                    current.Clear();
                }
                else
                    current.Append(c);
            }
        }
        fields.Add(current.ToString());
        return fields.ToArray();
    }

    private void HidePreviewPanel()
    {
        _previewTabs.Clear();
        _activePreviewTab = null;
        PreviewColumn.Width = new GridLength(0);
        SplitterColumn.Width = new GridLength(0);
        PreviewPanel.Visibility = Visibility.Collapsed;
        PreviewSplitter.Visibility = Visibility.Collapsed;
        PreviewWebView.Visibility = Visibility.Collapsed;
        PreviewTextScroll.Visibility = Visibility.Collapsed;
        PreviewDataGrid.Visibility = Visibility.Collapsed;
        try { if (_webViewInitialized) PreviewWebView.CoreWebView2?.NavigateToString("<html></html>"); } catch (Exception) { /* WebView 초기화 실패 */ }
    }

    /// <summary>프리뷰 탭 바 클릭 시 WebView2에서 포커스를 회수 (HWND airspace 문제 방지).</summary>
    private void PreviewTabBar_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        // WebView2가 포커스를 잡고 있으면 WPF 버튼 클릭이 무시될 수 있으므로 포커스를 강제 이동
        if (PreviewWebView.IsFocused || PreviewWebView.IsKeyboardFocusWithin)
        {
            var border = sender as Border;
            border?.Focus();
        }
    }

    private void BtnClosePreview_Click(object sender, RoutedEventArgs e)
    {
        HidePreviewPanel();
        BtnPreviewToggle.Visibility = Visibility.Collapsed;
    }

    private void BtnPreviewToggle_Click(object sender, RoutedEventArgs e)
    {
        if (PreviewPanel.Visibility == Visibility.Visible)
        {
            // 숨기기 (탭은 유지)
            PreviewPanel.Visibility = Visibility.Collapsed;
            PreviewSplitter.Visibility = Visibility.Collapsed;
            PreviewColumn.Width = new GridLength(0);
            SplitterColumn.Width = new GridLength(0);
        }
        else if (_previewTabs.Count > 0)
        {
            // 다시 열기
            PreviewPanel.Visibility = Visibility.Visible;
            PreviewSplitter.Visibility = Visibility.Visible;
            PreviewColumn.Width = new GridLength(420);
            SplitterColumn.Width = new GridLength(5);
            RebuildPreviewTabs();
            if (_activePreviewTab != null) LoadPreviewContent(_activePreviewTab);
        }
    }

    private void BtnOpenExternal_Click(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(_activePreviewTab) || !System.IO.File.Exists(_activePreviewTab))
            return;

        try
        {
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
            {
                FileName = _activePreviewTab,
                UseShellExecute = true,
            });
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"외부 프로그램 실행 오류: {ex.Message}");
        }
    }
}
