using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using AxCopilot.Services.Agent;

namespace AxCopilot.Views;

public partial class WorkflowAnalyzerWindow
{
    // ─── 타임라인 노드 생성 ────────────────────────────────────────

    private Border CreateTimelineNode(AgentEvent evt)
    {
        var (icon, iconColor, label) = GetEventVisual(evt);

        var node = new Border
        {
            Background = Brushes.Transparent,
            Margin = new Thickness(0, 1, 0, 1),
            Padding = new Thickness(8, 6, 8, 6),
            CornerRadius = new CornerRadius(8),
            Cursor = Cursors.Hand,
            Tag = evt,
        };

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

        // 아이콘 원
        var iconBorder = new Border
        {
            Width = 22, Height = 22,
            CornerRadius = new CornerRadius(11),
            Background = new SolidColorBrush(iconColor),
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Top,
            Margin = new Thickness(0, 2, 0, 0),
        };
        iconBorder.Child = new TextBlock
        {
            Text = icon,
            FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize = 10,
            Foreground = Brushes.White,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
        };
        Grid.SetColumn(iconBorder, 0);
        grid.Children.Add(iconBorder);

        // 타임라인 세로 선
        var line = new Rectangle
        {
            Width = 2,
            Fill = TryFindResource("BorderColor") as Brush ?? Brushes.Gray,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Stretch,
            Opacity = 0.4,
        };
        Grid.SetColumn(line, 1);
        grid.Children.Add(line);

        // 내용
        var content = new StackPanel { Margin = new Thickness(8, 0, 0, 0) };

        var headerPanel = new StackPanel { Orientation = Orientation.Horizontal };
        headerPanel.Children.Add(new TextBlock
        {
            Text = label,
            FontSize = 12,
            FontWeight = FontWeights.SemiBold,
            Foreground = TryFindResource("PrimaryText") as Brush ?? Brushes.White,
            VerticalAlignment = VerticalAlignment.Center,
        });

        if (evt.ElapsedMs > 0)
        {
            headerPanel.Children.Add(new TextBlock
            {
                Text = evt.ElapsedMs >= 1000 ? $"  {evt.ElapsedMs / 1000.0:F1}s" : $"  {evt.ElapsedMs}ms",
                FontSize = 10,
                Foreground = evt.ElapsedMs > 3000
                    ? Brushes.OrangeRed
                    : TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
                VerticalAlignment = VerticalAlignment.Center,
            });
        }

        headerPanel.Children.Add(new TextBlock
        {
            Text = $"  {evt.Timestamp:HH:mm:ss}",
            FontSize = 9,
            Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
            VerticalAlignment = VerticalAlignment.Center,
            Opacity = 0.6,
        });
        content.Children.Add(headerPanel);

        if (!string.IsNullOrEmpty(evt.Summary))
        {
            content.Children.Add(new TextBlock
            {
                Text = Truncate(evt.Summary, 120),
                FontSize = 11,
                Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
                TextWrapping = TextWrapping.Wrap,
                Margin = new Thickness(0, 2, 0, 0),
                LineHeight = 16,
            });
        }

        if (evt.InputTokens > 0 || evt.OutputTokens > 0)
        {
            var tokenPanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 3, 0, 0) };
            tokenPanel.Children.Add(CreateBadge($"↑{evt.InputTokens:#,0}", "#3B82F6"));
            tokenPanel.Children.Add(CreateBadge($"↓{evt.OutputTokens:#,0}", "#10B981"));
            content.Children.Add(tokenPanel);
        }

        Grid.SetColumn(content, 2);
        grid.Children.Add(content);
        node.Child = grid;

        var hoverBrush = TryFindResource("ItemHoverBackground") as Brush
            ?? new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
        node.MouseEnter += (_, _) => node.Background = hoverBrush;
        node.MouseLeave += (_, _) => node.Background = Brushes.Transparent;
        node.MouseLeftButtonUp += (_, _) => ShowDetail(evt);

        return node;
    }

    private static (string Icon, Color Color, string Label) GetEventVisual(AgentEvent evt)
    {
        return evt.Type switch
        {
            AgentEventType.Thinking  => ("\uE7BA", Color.FromRgb(0x60, 0xA5, 0xFA), "사고"),
            AgentEventType.Planning  => ("\uE9D5", Color.FromRgb(0xA7, 0x8B, 0xFA), "계획"),
            AgentEventType.StepStart => ("\uE72A", Color.FromRgb(0x60, 0xA5, 0xFA), $"단계 {evt.StepCurrent}/{evt.StepTotal}"),
            AgentEventType.StepDone  => ("\uE73E", Color.FromRgb(0x34, 0xD3, 0x99), $"단계 완료"),
            AgentEventType.ToolCall  => ("\uE756", Color.FromRgb(0xFB, 0xBF, 0x24), evt.ToolName),
            AgentEventType.ToolResult=> ("\uE73E", Color.FromRgb(0x34, 0xD3, 0x99), $"{evt.ToolName} ✓"),
            AgentEventType.SkillCall => ("\uE768", Color.FromRgb(0xA7, 0x8B, 0xFA), $"스킬: {evt.ToolName}"),
            AgentEventType.Error     => ("\uE783", Color.FromRgb(0xF8, 0x71, 0x71), $"{evt.ToolName} ✗"),
            AgentEventType.Complete  => ("\uE930", Color.FromRgb(0x34, 0xD3, 0x99), "완료"),
            AgentEventType.Decision  => ("\uE8C8", Color.FromRgb(0xFB, 0xBF, 0x24), "의사결정"),
            _                        => ("\uE946", Color.FromRgb(0x6B, 0x72, 0x80), "이벤트"),
        };
    }

    private static Border CreateBadge(string text, string colorHex)
    {
        var color = (Color)ColorConverter.ConvertFromString(colorHex);
        return new Border
        {
            Background = new SolidColorBrush(Color.FromArgb(0x30, color.R, color.G, color.B)),
            CornerRadius = new CornerRadius(4),
            Padding = new Thickness(5, 1, 5, 1),
            Margin = new Thickness(0, 0, 4, 0),
            Child = new TextBlock
            {
                Text = text,
                FontSize = 9,
                Foreground = new SolidColorBrush(color),
                FontWeight = FontWeights.SemiBold,
            },
        };
    }

    // ─── 상세 패널 ─────────────────────────────────────────────

    private void ShowDetail(AgentEvent evt)
    {
        DetailPanel.Visibility = Visibility.Visible;
        DetailPanel.Tag = evt;
        var (_, color, label) = GetEventVisual(evt);

        DetailTitle.Text = label;
        DetailBadge.Text = evt.Success ? "성공" : "실패";
        DetailBadge.Background = new SolidColorBrush(evt.Success
            ? Color.FromRgb(0x34, 0xD3, 0x99)
            : Color.FromRgb(0xF8, 0x71, 0x71));

        var meta = $"시간: {evt.Timestamp:HH:mm:ss.fff}";
        if (evt.ElapsedMs > 0)
            meta += $" | 소요: {(evt.ElapsedMs >= 1000 ? $"{evt.ElapsedMs / 1000.0:F1}s" : $"{evt.ElapsedMs}ms")}";
        if (evt.InputTokens > 0 || evt.OutputTokens > 0)
            meta += $" | 토큰: 입력 {evt.InputTokens:#,0} / 출력 {evt.OutputTokens:#,0}";
        if (evt.Iteration > 0)
            meta += $" | 반복 #{evt.Iteration}";
        DetailMeta.Text = meta;

        var contentText = evt.Summary ?? "";
        if (!string.IsNullOrEmpty(evt.ToolInput))
            contentText += $"\n\n파라미터:\n{Truncate(evt.ToolInput, 500)}";
        if (!string.IsNullOrEmpty(evt.FilePath))
            contentText += $"\n파일: {evt.FilePath}";
        DetailContent.Text = contentText;
    }

    // ─── 요약 카드 업데이트 ──────────────────────────────────────

    private void UpdateSummaryCards()
    {
        var elapsed = (DateTime.Now - _startTime).TotalSeconds;
        CardElapsed.Text = elapsed >= 60 ? $"{elapsed / 60:F0}m {elapsed % 60:F0}s" : $"{elapsed:F1}s";
        CardIterations.Text = _maxIteration.ToString();
        var totalTokens = _totalInputTokens + _totalOutputTokens;
        CardTokens.Text = totalTokens >= 1000 ? $"{totalTokens / 1000.0:F1}k" : totalTokens.ToString();
        CardInputTokens.Text = _totalInputTokens >= 1000 ? $"{_totalInputTokens / 1000.0:F1}k" : _totalInputTokens.ToString();
        CardOutputTokens.Text = _totalOutputTokens >= 1000 ? $"{_totalOutputTokens / 1000.0:F1}k" : _totalOutputTokens.ToString();
        CardToolCalls.Text = _totalToolCalls.ToString();
    }

    // ─── 유틸리티 ────────────────────────────────────────────────

    private static string FormatMs(long ms)
        => ms >= 1000 ? $"{ms / 1000.0:F1}s" : $"{ms}ms";

    private static string Truncate(string text, int maxLen)
        => text.Length <= maxLen ? text : text[..maxLen] + "…";

    // ─── 윈도우 이벤트 ────────────────────────────────────────────

    private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // 타이틀 바 버튼 영역 클릭 시 드래그 무시 (DragMove가 마우스를 캡처하여 MouseLeftButtonUp 차단 방지)
        var src = e.OriginalSource as DependencyObject;
        while (src != null && src != sender)
        {
            if (src is Border b && b.Name is "BtnClose" or "BtnMinimize" or "BtnClear")
                return;
            src = VisualTreeHelper.GetParent(src);
        }
        if (e.ClickCount == 1) DragMove();
    }

    private void BtnClose_Click(object sender, MouseButtonEventArgs e) => Hide();
    private void BtnMinimize_Click(object sender, MouseButtonEventArgs e) => WindowState = WindowState.Minimized;
    private void BtnClear_Click(object sender, MouseButtonEventArgs e) => Reset();

    private void TitleBtn_MouseEnter(object sender, MouseEventArgs e)
    {
        if (sender is Border b)
            b.Background = TryFindResource("ItemHoverBackground") as Brush
                ?? new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
    }

    private void TitleBtn_MouseLeave(object sender, MouseEventArgs e)
    {
        if (sender is Border b)
            b.Background = Brushes.Transparent;
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_NCHITTEST)
        {
            var pt = PointFromScreen(new Point(
                (short)(lParam.ToInt32() & 0xFFFF),
                (short)((lParam.ToInt32() >> 16) & 0xFFFF)));
            const double grip = 8;
            var w = ActualWidth;
            var h = ActualHeight;

            if (pt.X < grip && pt.Y < grip) { handled = true; return (IntPtr)HTTOPLEFT; }
            if (pt.X > w - grip && pt.Y < grip) { handled = true; return (IntPtr)HTTOPRIGHT; }
            if (pt.X < grip && pt.Y > h - grip) { handled = true; return (IntPtr)HTBOTTOMLEFT; }
            if (pt.X > w - grip && pt.Y > h - grip) { handled = true; return (IntPtr)HTBOTTOMRIGHT; }
            if (pt.X < grip) { handled = true; return (IntPtr)HTLEFT; }
            if (pt.X > w - grip) { handled = true; return (IntPtr)HTRIGHT; }
            if (pt.Y < grip) { handled = true; return (IntPtr)HTTOP; }
            if (pt.Y > h - grip) { handled = true; return (IntPtr)HTBOTTOM; }
        }
        return IntPtr.Zero;
    }
}
