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

namespace AxCopilot.Views;

public partial class ChatWindow
{
    // ─── 응답 재생성 ──────────────────────────────────────────────────────

    private async Task RegenerateLastAsync()
    {
        if (_isStreaming) return;
        ChatConversation conv;
        lock (_convLock)
        {
            if (_currentConversation == null) return;
            conv = _currentConversation;
        }

        // 마지막 assistant 메시지 제거
        lock (_convLock)
        {
            if (conv.Messages.Count > 0 && conv.Messages[^1].Role == "assistant")
                conv.Messages.RemoveAt(conv.Messages.Count - 1);
        }

        // UI에서 마지막 AI 응답 제거
        if (MessagePanel.Children.Count > 0)
            MessagePanel.Children.RemoveAt(MessagePanel.Children.Count - 1);

        // 재전송
        await SendRegenerateAsync(conv);
    }

    /// <summary>"수정 후 재시도" — 피드백 입력 패널을 표시하고, 사용자 지시를 추가하여 재생성합니다.</summary>
    private void ShowRetryWithFeedbackInput()
    {
        if (_isStreaming) return;
        var accentBrush = ThemeResourceHelper.Accent(this);
        var itemBg = ThemeResourceHelper.ItemBg(this);
        var primaryText = ThemeResourceHelper.Primary(this);
        var secondaryText = ThemeResourceHelper.Secondary(this);
        var borderBrush = ThemeResourceHelper.Border(this);

        var container = new Border
        {
            Margin = new Thickness(40, 4, 40, 8),
            Padding = new Thickness(14, 10, 14, 10),
            CornerRadius = new CornerRadius(12),
            Background = itemBg,
            HorizontalAlignment = HorizontalAlignment.Stretch,
        };

        var stack = new StackPanel();
        stack.Children.Add(new TextBlock
        {
            Text = "어떻게 수정하면 좋을지 알려주세요:",
            FontSize = 12,
            Foreground = secondaryText,
            Margin = new Thickness(0, 0, 0, 6),
        });

        var textBox = new TextBox
        {
            MinHeight = 38,
            MaxHeight = 80,
            AcceptsReturn = true,
            TextWrapping = TextWrapping.Wrap,
            FontSize = 13,
            Background = ThemeResourceHelper.Background(this),
            Foreground = primaryText,
            CaretBrush = primaryText,
            BorderBrush = borderBrush,
            BorderThickness = new Thickness(1),
            Padding = new Thickness(10, 6, 10, 6),
        };
        stack.Children.Add(textBox);

        var btnRow = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            HorizontalAlignment = HorizontalAlignment.Right,
            Margin = new Thickness(0, 8, 0, 0),
        };

        var sendBtn = new Border
        {
            Background = accentBrush,
            CornerRadius = new CornerRadius(8),
            Padding = new Thickness(14, 6, 14, 6),
            Cursor = Cursors.Hand,
            Margin = new Thickness(6, 0, 0, 0),
        };
        sendBtn.Child = new TextBlock { Text = "재시도", FontSize = 12, FontWeight = FontWeights.SemiBold, Foreground = Brushes.White };
        sendBtn.MouseEnter += (s, _) => ((Border)s).Opacity = 0.85;
        sendBtn.MouseLeave += (s, _) => ((Border)s).Opacity = 1.0;
        sendBtn.MouseLeftButtonUp += (_, _) =>
        {
            var feedback = textBox.Text.Trim();
            if (string.IsNullOrEmpty(feedback)) return;
            MessagePanel.Children.Remove(container);
            _ = RetryWithFeedbackAsync(feedback);
        };

        var cancelBtn = new Border
        {
            Background = Brushes.Transparent,
            CornerRadius = new CornerRadius(8),
            Padding = new Thickness(12, 6, 12, 6),
            Cursor = Cursors.Hand,
        };
        cancelBtn.Child = new TextBlock { Text = "취소", FontSize = 12, Foreground = secondaryText };
        cancelBtn.MouseLeftButtonUp += (_, _) => MessagePanel.Children.Remove(container);

        btnRow.Children.Add(cancelBtn);
        btnRow.Children.Add(sendBtn);
        stack.Children.Add(btnRow);
        container.Child = stack;

        ApplyMessageEntryAnimation(container);
        MessagePanel.Children.Add(container);
        ForceScrollToEnd();
        textBox.Focus();
    }

    /// <summary>사용자 피드백과 함께 마지막 응답을 재생성합니다.</summary>
    private async Task RetryWithFeedbackAsync(string feedback)
    {
        if (_isStreaming) return;
        ChatConversation conv;
        lock (_convLock)
        {
            if (_currentConversation == null) return;
            conv = _currentConversation;
        }

        // 마지막 assistant 메시지 제거
        lock (_convLock)
        {
            if (conv.Messages.Count > 0 && conv.Messages[^1].Role == "assistant")
                conv.Messages.RemoveAt(conv.Messages.Count - 1);
        }

        // UI에서 마지막 AI 응답 제거
        if (MessagePanel.Children.Count > 0)
            MessagePanel.Children.RemoveAt(MessagePanel.Children.Count - 1);

        // 피드백을 사용자 메시지로 추가
        var feedbackMsg = new ChatMessage
        {
            Role = "user",
            Content = $"[이전 응답에 대한 수정 요청] {feedback}\n\n위 피드백을 반영하여 다시 작성해주세요."
        };
        lock (_convLock) conv.Messages.Add(feedbackMsg);

        // 피드백 메시지 UI 표시
        AddMessageBubble("user", $"[수정 요청] {feedback}", true);

        // 재전송
        await SendRegenerateAsync(conv);
    }

    private async Task SendRegenerateAsync(ChatConversation conv)
    {
        _isStreaming = true;
        BtnSend.IsEnabled = false;
        BtnSend.Visibility = Visibility.Collapsed;
        BtnStop.Visibility = Visibility.Visible;
        _streamCts = new CancellationTokenSource();

        var assistantMsg = new ChatMessage { Role = "assistant", Content = "" };
        lock (_convLock) conv.Messages.Add(assistantMsg);

        var streamContainer = CreateStreamingContainer(out var streamText);
        MessagePanel.Children.Add(streamContainer);
        ForceScrollToEnd(); // 응답 시작 시 강제 하단 이동

        var sb = new System.Text.StringBuilder();
        _activeStreamText    = streamText;
        _cachedStreamContent = "";
        _displayedLength     = 0;
        _cursorVisible       = true;
        _aiIconPulseStopped  = false;
        _cursorTimer.Start();
        _typingTimer.Start();
        _streamStartTime = DateTime.UtcNow;
        _elapsedTimer.Start();
        SetStatus("에이전트 작업 중...", spinning: true);

        try
        {
            List<ChatMessage> sendMessages;
            lock (_convLock) sendMessages = conv.Messages.SkipLast(1).ToList();
            if (!string.IsNullOrEmpty(conv.SystemCommand))
                sendMessages.Insert(0, new ChatMessage { Role = "system", Content = conv.SystemCommand });

            await foreach (var chunk in _llm.StreamAsync(sendMessages, _streamCts.Token))
            {
                sb.Append(chunk);
                StopAiIconPulse();
                _cachedStreamContent = sb.ToString();
                await Dispatcher.InvokeAsync(() => { }, DispatcherPriority.Background);
            }
            _cachedStreamContent = sb.ToString();
            assistantMsg.Content = _cachedStreamContent;

            // 타이핑 애니메이션이 남은 버퍼를 소진할 때까지 대기 (최대 600ms)
            var drainStart2 = DateTime.UtcNow;
            while (_displayedLength < _cachedStreamContent.Length
                   && (DateTime.UtcNow - drainStart2).TotalMilliseconds < 600)
            {
                await Dispatcher.InvokeAsync(() => { }, DispatcherPriority.Background);
            }
        }
        catch (OperationCanceledException)
        {
            if (sb.Length == 0) sb.Append("(취소됨)");
            assistantMsg.Content = sb.ToString();
        }
        catch (Exception ex)
        {
            var errMsg = $"⚠ 오류: {ex.Message}";
            sb.Clear(); sb.Append(errMsg);
            assistantMsg.Content = errMsg;
            AddRetryButton();
        }
        finally
        {
            _cursorTimer.Stop();
            _elapsedTimer.Stop();
            _typingTimer.Stop();
            HideStickyProgress();            // 에이전트 프로그레스 바 + 타이머 정리
            StopRainbowGlow();               // 레인보우 글로우 종료
            _activeStreamText    = null;
            _elapsedLabel        = null;
            _cachedStreamContent = "";
            _isStreaming          = false;
            BtnSend.IsEnabled     = true;
            BtnStop.Visibility    = Visibility.Collapsed;
            BtnSend.Visibility    = Visibility.Visible;
            _streamCts?.Dispose();
            _streamCts = null;
            SetStatusIdle();
        }

        FinalizeStreamingContainer(streamContainer, streamText, assistantMsg.Content, assistantMsg);
        AutoScrollIfNeeded();

        try { _storage.Save(conv); } catch (Exception ex) { LogService.Debug($"대화 저장 실패: {ex.Message}"); }
        _tabConversationId[conv.Tab ?? _activeTab] = conv.Id;
        RefreshConversationList();
    }

    /// <summary>메시지 버블의 MaxWidth를 창 너비에 비례하여 계산합니다 (최소 500, 최대 1200).</summary>
    private double GetMessageMaxWidth()
    {
        var scrollWidth = MessageScroll.ActualWidth;
        if (scrollWidth < 100) scrollWidth = 700; // 초기화 전 기본값
        // 좌우 마진(40+80=120)을 빼고 전체의 90%
        var maxW = (scrollWidth - 120) * 0.90;
        return Math.Clamp(maxW, 500, 1200);
    }
}
