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

namespace AxCopilot.Views;

public partial class ChatWindow
{
    // ─── 대화 목록 ────────────────────────────────────────────────────────

    public void RefreshConversationList()
    {
        var metas = _storage.LoadAllMeta();
        // 프리셋 카테고리 → 아이콘/색상 매핑 (ChatCategory에 없는 코워크/코드 카테고리 지원)
        var allPresets = Services.PresetService.GetByTabWithCustom("Cowork", Llm.CustomPresets)
            .Concat(Services.PresetService.GetByTabWithCustom("Code", Llm.CustomPresets))
            .Concat(Services.PresetService.GetByTabWithCustom("Chat", Llm.CustomPresets));
        var presetMap = new Dictionary<string, (string Symbol, string Color)>(StringComparer.OrdinalIgnoreCase);
        foreach (var p in allPresets)
            presetMap.TryAdd(p.Category, (p.Symbol, p.Color));

        var items = metas.Select(c =>
        {
            var symbol = ChatCategory.GetSymbol(c.Category);
            var color = ChatCategory.GetColor(c.Category);
            // ChatCategory 기본값이면 프리셋에서 검색
            if (symbol == "\uE8BD" && color == "#6B7280" && c.Category != ChatCategory.General)
            {
                if (presetMap.TryGetValue(c.Category, out var pm))
                {
                    symbol = pm.Symbol;
                    color = pm.Color;
                }
            }
            return new ConversationMeta
            {
                Id = c.Id,
                Title = c.Title,
                Pinned = c.Pinned,
                Category = c.Category,
                Symbol = symbol,
                ColorHex = color,
                Tab = string.IsNullOrEmpty(c.Tab) ? "Chat" : c.Tab,
                UpdatedAtText = FormatDate(c.UpdatedAt),
                UpdatedAt = c.UpdatedAt,
                Preview = c.Preview ?? "",
                ParentId = c.ParentId,
            };
        }).ToList();

        // 탭 필터 — 현재 활성 탭의 대화만 표시
        items = items.Where(i => i.Tab == _activeTab).ToList();

        // 카테고리 필터 적용
        if (_selectedCategory == "__custom__")
        {
            // 커스텀 프리셋으로 만든 대화만 표시
            var customCats = Llm.CustomPresets
                .Select(c => $"custom_{c.Id}").ToHashSet();
            items = items.Where(i => customCats.Contains(i.Category)).ToList();
        }
        else if (!string.IsNullOrEmpty(_selectedCategory))
            items = items.Where(i => i.Category == _selectedCategory).ToList();

        // 검색 필터 (제목 + 내용 미리보기)
        var search = SearchBox?.Text?.Trim() ?? "";
        if (!string.IsNullOrEmpty(search))
            items = items.Where(i =>
                i.Title.Contains(search, StringComparison.OrdinalIgnoreCase) ||
                i.Preview.Contains(search, StringComparison.OrdinalIgnoreCase)
            ).ToList();

        RenderConversationList(items);
    }

    private const int ConversationPageSize = 50;
    private List<ConversationMeta>? _pendingConversations;

    private void RenderConversationList(List<ConversationMeta> items)
    {
        ConversationPanel.Children.Clear();
        _pendingConversations = null;

        if (items.Count == 0)
        {
            var empty = new TextBlock
            {
                Text = "대화가 없습니다",
                FontSize = 12,
                Foreground = (ThemeResourceHelper.Secondary(this)),
                HorizontalAlignment = HorizontalAlignment.Center,
                Margin = new Thickness(0, 20, 0, 0)
            };
            ConversationPanel.Children.Add(empty);
            return;
        }

        // 오늘 / 이전 그룹 분리
        var today = DateTime.Today;
        var todayItems = items.Where(i => i.UpdatedAt.Date == today).ToList();
        var olderItems = items.Where(i => i.UpdatedAt.Date < today).ToList();

        var allOrdered = new List<(string Group, ConversationMeta Item)>();
        foreach (var item in todayItems) allOrdered.Add(("오늘", item));
        foreach (var item in olderItems) allOrdered.Add(("이전", item));

        // 첫 페이지만 렌더링
        var firstPage = allOrdered.Take(ConversationPageSize).ToList();
        string? lastGroup = null;
        foreach (var (group, item) in firstPage)
        {
            if (group != lastGroup) { AddGroupHeader(group); lastGroup = group; }
            AddConversationItem(item);
        }

        // 나머지가 있으면 "더 보기" 버튼
        if (allOrdered.Count > ConversationPageSize)
        {
            _pendingConversations = items;
            AddLoadMoreButton(allOrdered.Count - ConversationPageSize);
        }
    }

    private void AddLoadMoreButton(int remaining)
    {
        var secondaryText = ThemeResourceHelper.Secondary(this);
        var accentBrush = ThemeResourceHelper.Accent(this);
        var btn = new Border
        {
            Background = Brushes.Transparent,
            CornerRadius = new CornerRadius(8),
            Cursor = Cursors.Hand,
            Padding = new Thickness(8, 10, 8, 10),
            Margin = new Thickness(6, 4, 6, 4),
            HorizontalAlignment = HorizontalAlignment.Stretch,
        };
        var sp = new StackPanel { HorizontalAlignment = HorizontalAlignment.Center };
        sp.Children.Add(new TextBlock
        {
            Text = $"더 보기 ({remaining}개 남음)",
            FontSize = 12,
            Foreground = accentBrush,
            HorizontalAlignment = HorizontalAlignment.Center,
        });
        btn.Child = sp;
        btn.MouseEnter += (s, _) => { if (s is Border b) b.Background = new SolidColorBrush(Color.FromArgb(0x12, 0xFF, 0xFF, 0xFF)); };
        btn.MouseLeave += (s, _) => { if (s is Border b) b.Background = Brushes.Transparent; };
        btn.MouseLeftButtonUp += (_, _) =>
        {
            // 전체 목록 렌더링
            if (_pendingConversations != null)
            {
                var all = _pendingConversations;
                _pendingConversations = null;
                ConversationPanel.Children.Clear();

                var today = DateTime.Today;
                var todayItems = all.Where(i => i.UpdatedAt.Date == today).ToList();
                var olderItems = all.Where(i => i.UpdatedAt.Date < today).ToList();

                if (todayItems.Count > 0)
                {
                    AddGroupHeader("오늘");
                    foreach (var item in todayItems) AddConversationItem(item);
                }
                if (olderItems.Count > 0)
                {
                    AddGroupHeader("이전");
                    foreach (var item in olderItems) AddConversationItem(item);
                }
            }
        };
        ConversationPanel.Children.Add(btn);
    }

    private void AddGroupHeader(string text)
    {
        var header = new TextBlock
        {
            Text = text,
            FontSize = 11,
            FontWeight = FontWeights.SemiBold,
            Foreground = (ThemeResourceHelper.Secondary(this)),
            Margin = new Thickness(8, 12, 0, 4)
        };
        ConversationPanel.Children.Add(header);
    }

    private void AddConversationItem(ConversationMeta item)
    {
        var isSelected = false;
        lock (_convLock)
            isSelected = _currentConversation?.Id == item.Id;

        var isBranch = !string.IsNullOrEmpty(item.ParentId);
        var border = new Border
        {
            Background = isSelected
                ? new SolidColorBrush(Color.FromArgb(0x30, 0x4B, 0x5E, 0xFC))
                : Brushes.Transparent,
            CornerRadius = new CornerRadius(8),
            Padding = new Thickness(10, 8, 10, 8),
            Margin = isBranch ? new Thickness(16, 1, 0, 1) : new Thickness(0, 1, 0, 1),
            Cursor = Cursors.Hand
        };

        var grid = new Grid();
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(28) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

        // 카테고리 아이콘 (고정 시 핀 아이콘, 그 외 카테고리 색상)
        Brush iconBrush;
        if (item.Pinned)
            iconBrush = Brushes.Orange;
        else
        {
            try { iconBrush = ThemeResourceHelper.HexBrush(item.ColorHex); }
            catch (Exception) { iconBrush = ThemeResourceHelper.Accent(this); }
        }
        var iconText = item.Pinned ? "\uE718" : !string.IsNullOrEmpty(item.ParentId) ? "\uE8A5" : item.Symbol;
        if (!string.IsNullOrEmpty(item.ParentId)) iconBrush = new SolidColorBrush(Color.FromRgb(0x8B, 0x5C, 0xF6)); // 분기: 보라색
        var icon = new TextBlock
        {
            Text = iconText,
            FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize = 13,
            Foreground = iconBrush,
            VerticalAlignment = VerticalAlignment.Center
        };
        Grid.SetColumn(icon, 0);
        grid.Children.Add(icon);

        // 제목 + 날짜 (선택 시 약간 밝게)
        var titleColor = ThemeResourceHelper.Primary(this);
        var dateColor = ThemeResourceHelper.HintFg(this);

        var stack = new StackPanel { VerticalAlignment = VerticalAlignment.Center };
        var title = new TextBlock
        {
            Text = item.Title,
            FontSize = 12.5,
            Foreground = titleColor,
            TextTrimming = TextTrimming.CharacterEllipsis
        };
        var date = new TextBlock
        {
            Text = item.UpdatedAtText,
            FontSize = 10,
            Foreground = dateColor,
            Margin = new Thickness(0, 2, 0, 0)
        };
        stack.Children.Add(title);
        stack.Children.Add(date);
        Grid.SetColumn(stack, 1);
        grid.Children.Add(stack);

        // 카테고리 변경 버튼 (호버 시 표시)
        var catBtn = new Button
        {
            Content = new TextBlock
            {
                Text = "\uE70F", // Edit
                FontFamily = ThemeResourceHelper.SegoeMdl2,
                FontSize = 10,
                Foreground = (ThemeResourceHelper.Secondary(this))
            },
            Background = Brushes.Transparent,
            BorderThickness = new Thickness(0),
            Cursor = Cursors.Hand,
            VerticalAlignment = VerticalAlignment.Center,
            Visibility = Visibility.Collapsed,
            Padding = new Thickness(4),
            ToolTip = _activeTab == "Cowork" ? "작업 유형" : "대화 주제 변경"
        };
        var capturedId = item.Id;
        catBtn.Click += (_, _) => ShowConversationMenu(capturedId);
        Grid.SetColumn(catBtn, 2);
        grid.Children.Add(catBtn);

        // 선택 시 좌측 액센트 바
        if (isSelected)
        {
            border.BorderBrush = ThemeResourceHelper.Accent(this);
            border.BorderThickness = new Thickness(2, 0, 0, 0);
        }

        border.Child = grid;

        // 호버 이벤트 — 배경 + 미세 확대
        border.RenderTransformOrigin = new Point(0.5, 0.5);
        border.RenderTransform = new ScaleTransform(1, 1);
        var selectedBg = new SolidColorBrush(Color.FromArgb(0x30, 0x4B, 0x5E, 0xFC));
        border.MouseEnter += (_, _) =>
        {
            if (!isSelected)
                border.Background = new SolidColorBrush(Color.FromArgb(0x15, 0xFF, 0xFF, 0xFF));
            catBtn.Visibility = Visibility.Visible;
            var st = border.RenderTransform as ScaleTransform;
            st?.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(1.02, TimeSpan.FromMilliseconds(120)));
            st?.BeginAnimation(ScaleTransform.ScaleYProperty, new DoubleAnimation(1.02, TimeSpan.FromMilliseconds(120)));
        };
        border.MouseLeave += (_, _) =>
        {
            if (!isSelected)
                border.Background = Brushes.Transparent;
            catBtn.Visibility = Visibility.Collapsed;
            var st = border.RenderTransform as ScaleTransform;
            st?.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(150)));
            st?.BeginAnimation(ScaleTransform.ScaleYProperty, new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(150)));
        };

        // 클릭 — 이미 선택된 대화면 제목 편집, 아니면 대화 전환
        border.MouseLeftButtonDown += (_, _) =>
        {
            try
            {
                if (isSelected)
                {
                    // 이미 선택된 대화 → 제목 편집 모드
                    EnterTitleEditMode(title, item.Id, titleColor);
                    return;
                }
                // 스트리밍 중이면 취소
                if (_isStreaming)
                {
                    _streamCts?.Cancel();
                    _cursorTimer.Stop();
                    _typingTimer.Stop();
                    _elapsedTimer.Stop();
                    _activeStreamText = null;
                    _elapsedLabel = null;
                    _isStreaming = false;
                }
                var conv = _storage.Load(item.Id);
                if (conv != null)
                {
                    // Tab 보정
                    if (string.IsNullOrEmpty(conv.Tab)) conv.Tab = _activeTab;
                    lock (_convLock) _currentConversation = conv;
                    _tabConversationId[_activeTab] = conv.Id;
                    UpdateChatTitle();
                    RenderMessages();
                    RefreshConversationList();
                }
            }
            catch (Exception ex)
            {
                LogService.Error($"대화 전환 오류: {ex.Message}");
            }
        };

        // 우클릭 → 대화 관리 메뉴 바로 표시
        border.MouseRightButtonUp += (_, me) =>
        {
            me.Handled = true;
            // 선택되지 않은 대화를 우클릭하면 먼저 선택
            if (!isSelected)
            {
                var conv = _storage.Load(item.Id);
                if (conv != null)
                {
                    if (string.IsNullOrEmpty(conv.Tab)) conv.Tab = _activeTab;
                    lock (_convLock) _currentConversation = conv;
                    _tabConversationId[_activeTab] = conv.Id;
                    UpdateChatTitle();
                    RenderMessages();
                }
            }
            // Dispatcher로 지연 호출 — 마우스 이벤트 완료 후 Popup 열기
            Dispatcher.BeginInvoke(new Action(() => ShowConversationMenu(item.Id)), System.Windows.Threading.DispatcherPriority.Input);
        };

        ConversationPanel.Children.Add(border);
    }

    // ─── 검색 ────────────────────────────────────────────────────────────

    private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        RefreshConversationList();
    }

    private static string FormatDate(DateTime dt)
    {
        var diff = DateTime.Now - dt;
        if (diff.TotalMinutes < 1) return "방금 전";
        if (diff.TotalHours < 1) return $"{(int)diff.TotalMinutes}분 전";
        if (diff.TotalDays < 1) return $"{(int)diff.TotalHours}시간 전";
        if (diff.TotalDays < 7) return $"{(int)diff.TotalDays}일 전";
        return dt.ToString("MM/dd");
    }

    private void UpdateChatTitle()
    {
        lock (_convLock)
        {
            ChatTitle.Text = _currentConversation?.Title ?? "";
        }
    }
}
