using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;

namespace AxCopilot.Views;

/// <summary>
/// 에이전트가 사용자에게 질문할 때 표시하는 커스텀 대화 상자.
/// 선택지 버튼 + 직접 입력 텍스트 박스를 제공합니다.
/// </summary>
internal sealed class UserAskDialog : Window
{
    private string _selectedResponse = "";
    private readonly TextBox _customInput;
    private readonly StackPanel _optionPanel;

    public string SelectedResponse => _selectedResponse;

    private UserAskDialog(string question, List<string> options, string defaultValue)
    {
        Width = 460;
        MinWidth = 380;
        MaxWidth = 560;
        SizeToContent = SizeToContent.Height;
        WindowStartupLocation = WindowStartupLocation.CenterScreen;
        ResizeMode = ResizeMode.NoResize;
        WindowStyle = WindowStyle.None;
        AllowsTransparency = true;
        Background = Brushes.Transparent;
        Topmost = true;

        var bgBrush = Application.Current.TryFindResource("LauncherBackground") as Brush
                      ?? new SolidColorBrush(Color.FromRgb(0x1A, 0x1B, 0x2E));
        var primaryText = Application.Current.TryFindResource("PrimaryText") as Brush ?? Brushes.White;
        var secondaryText = Application.Current.TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
        var accentBrush = Application.Current.TryFindResource("AccentColor") as Brush
                          ?? new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC));
        var borderBrush = Application.Current.TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
        var itemBg = Application.Current.TryFindResource("ItemBackground") as Brush
                     ?? new SolidColorBrush(Color.FromRgb(0x2A, 0x2B, 0x40));
        var hoverBg = Application.Current.TryFindResource("ItemHoverBackground") as Brush
                      ?? new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));

        // 루트
        var root = new Border
        {
            Background = bgBrush,
            CornerRadius = new CornerRadius(16),
            BorderBrush = borderBrush,
            BorderThickness = new Thickness(1),
            Padding = new Thickness(24, 20, 24, 18),
            Effect = new DropShadowEffect
            {
                BlurRadius = 24, ShadowDepth = 4, Opacity = 0.3, Color = Colors.Black,
            },
        };

        var stack = new StackPanel();

        // 타이틀 바 (드래그 가능)
        var titleBar = new Grid { Margin = new Thickness(0, 0, 0, 12) };
        titleBar.MouseLeftButtonDown += (_, _) => { try { DragMove(); } catch (Exception) { } };
        var titleSp = new StackPanel { Orientation = Orientation.Horizontal };
        titleSp.Children.Add(new TextBlock
        {
            Text = "\uE9CE",
            FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize = 16,
            Foreground = accentBrush,
            VerticalAlignment = VerticalAlignment.Center,
            Margin = new Thickness(0, 0, 8, 0),
        });
        titleSp.Children.Add(new TextBlock
        {
            Text = "AX Agent — 질문",
            FontSize = 14,
            FontWeight = FontWeights.SemiBold,
            Foreground = primaryText,
            VerticalAlignment = VerticalAlignment.Center,
        });
        titleBar.Children.Add(titleSp);
        stack.Children.Add(titleBar);

        // 구분선
        stack.Children.Add(new Border
        {
            Height = 1,
            Background = borderBrush,
            Opacity = 0.3,
            Margin = new Thickness(0, 0, 0, 14),
        });

        // 질문 텍스트
        stack.Children.Add(new TextBlock
        {
            Text = question,
            FontSize = 13.5,
            Foreground = primaryText,
            TextWrapping = TextWrapping.Wrap,
            Margin = new Thickness(0, 0, 0, 16),
            LineHeight = 20,
        });

        // 선택지 버튼들
        _optionPanel = new StackPanel { Margin = new Thickness(0, 0, 0, 12) };
        Border? selectedBorder = null;

        foreach (var option in options)
        {
            var capturedOption = option;
            var optBorder = new Border
            {
                Background = itemBg,
                CornerRadius = new CornerRadius(10),
                Padding = new Thickness(14, 10, 14, 10),
                Margin = new Thickness(0, 0, 0, 6),
                Cursor = Cursors.Hand,
                BorderBrush = Brushes.Transparent,
                BorderThickness = new Thickness(1.5),
            };

            var optSp = new StackPanel { Orientation = Orientation.Horizontal };
            var radioCircle = new Border
            {
                Width = 18, Height = 18,
                CornerRadius = new CornerRadius(9),
                BorderBrush = secondaryText,
                BorderThickness = new Thickness(1.5),
                Margin = new Thickness(0, 0, 10, 0),
                VerticalAlignment = VerticalAlignment.Center,
                Child = new Border
                {
                    Width = 10, Height = 10,
                    CornerRadius = new CornerRadius(5),
                    Background = Brushes.Transparent,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center,
                },
            };
            optSp.Children.Add(radioCircle);
            optSp.Children.Add(new TextBlock
            {
                Text = capturedOption,
                FontSize = 13,
                Foreground = primaryText,
                VerticalAlignment = VerticalAlignment.Center,
                TextWrapping = TextWrapping.Wrap,
            });
            optBorder.Child = optSp;

            optBorder.MouseEnter += (s, _) =>
            {
                var b = (Border)s;
                if (b.BorderBrush != accentBrush)
                    b.Background = hoverBg;
            };
            optBorder.MouseLeave += (s, _) =>
            {
                var b = (Border)s;
                if (b.BorderBrush != accentBrush)
                    b.Background = itemBg;
            };
            optBorder.MouseLeftButtonUp += (s, _) =>
            {
                // 이전 선택 해제
                if (selectedBorder != null)
                {
                    selectedBorder.BorderBrush = Brushes.Transparent;
                    selectedBorder.Background = itemBg;
                    var prevCircle = FindRadioCircle(selectedBorder);
                    if (prevCircle != null) prevCircle.Background = Brushes.Transparent;
                }

                // 현재 선택
                var cur = (Border)s;
                cur.BorderBrush = accentBrush;
                cur.Background = new SolidColorBrush(Color.FromArgb(0x15,
                    ((SolidColorBrush)accentBrush).Color.R,
                    ((SolidColorBrush)accentBrush).Color.G,
                    ((SolidColorBrush)accentBrush).Color.B));
                var circle = FindRadioCircle(cur);
                if (circle != null) circle.Background = accentBrush;
                selectedBorder = cur;

                _selectedResponse = capturedOption;
                if (_customInput != null) _customInput.Text = ""; // 선택지 고르면 직접 입력 초기화
            };

            _optionPanel.Children.Add(optBorder);
        }
        stack.Children.Add(_optionPanel);

        // 직접 입력 영역
        stack.Children.Add(new TextBlock
        {
            Text = "또는 직접 입력:",
            FontSize = 11.5,
            Foreground = secondaryText,
            Margin = new Thickness(2, 0, 0, 6),
        });

        _customInput = new TextBox
        {
            MinHeight = 40,
            MaxHeight = 100,
            AcceptsReturn = true,
            TextWrapping = TextWrapping.Wrap,
            FontSize = 13,
            Background = itemBg,
            Foreground = primaryText,
            CaretBrush = primaryText,
            BorderBrush = borderBrush,
            BorderThickness = new Thickness(1),
            Padding = new Thickness(10, 8, 10, 8),
            Text = defaultValue,
        };
        _customInput.TextChanged += (_, _) =>
        {
            if (!string.IsNullOrEmpty(_customInput.Text))
            {
                // 직접 입력 시 선택 해제
                if (selectedBorder != null)
                {
                    selectedBorder.BorderBrush = Brushes.Transparent;
                    selectedBorder.Background = itemBg;
                    var prevCircle = FindRadioCircle(selectedBorder);
                    if (prevCircle != null) prevCircle.Background = Brushes.Transparent;
                    selectedBorder = null;
                }
                _selectedResponse = _customInput.Text;
            }
        };
        stack.Children.Add(_customInput);

        // 하단 버튼
        var btnPanel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            HorizontalAlignment = HorizontalAlignment.Right,
            Margin = new Thickness(0, 16, 0, 0),
        };

        // 확인 버튼
        var confirmBtn = new Border
        {
            Background = accentBrush,
            CornerRadius = new CornerRadius(10),
            Padding = new Thickness(20, 9, 20, 9),
            Cursor = Cursors.Hand,
            Margin = new Thickness(8, 0, 0, 0),
        };
        confirmBtn.Child = new TextBlock
        {
            Text = "확인",
            FontSize = 13,
            FontWeight = FontWeights.SemiBold,
            Foreground = Brushes.White,
        };
        confirmBtn.MouseEnter += (s, _) => ((Border)s).Opacity = 0.85;
        confirmBtn.MouseLeave += (s, _) => ((Border)s).Opacity = 1.0;
        confirmBtn.MouseLeftButtonUp += (_, _) =>
        {
            if (string.IsNullOrWhiteSpace(_selectedResponse) && !string.IsNullOrWhiteSpace(defaultValue))
                _selectedResponse = defaultValue;
            DialogResult = true;
            Close();
        };
        btnPanel.Children.Add(confirmBtn);

        // 취소 버튼
        var cancelBtn = new Border
        {
            Background = Brushes.Transparent,
            CornerRadius = new CornerRadius(10),
            Padding = new Thickness(16, 9, 16, 9),
            Cursor = Cursors.Hand,
            BorderBrush = new SolidColorBrush(Color.FromArgb(0x40, 0xDC, 0x26, 0x26)),
            BorderThickness = new Thickness(1),
        };
        cancelBtn.Child = new TextBlock
        {
            Text = "취소",
            FontSize = 13,
            Foreground = new SolidColorBrush(Color.FromRgb(0xDC, 0x26, 0x26)),
        };
        cancelBtn.MouseEnter += (s, _) => ((Border)s).Opacity = 0.85;
        cancelBtn.MouseLeave += (s, _) => ((Border)s).Opacity = 1.0;
        cancelBtn.MouseLeftButtonUp += (_, _) =>
        {
            _selectedResponse = "";
            DialogResult = false;
            Close();
        };
        // 취소를 왼쪽에 배치
        btnPanel.Children.Insert(0, cancelBtn);

        stack.Children.Add(btnPanel);

        root.Child = stack;
        Content = root;

        // 등장 애니메이션
        root.RenderTransformOrigin = new Point(0.5, 0.5);
        root.RenderTransform = new ScaleTransform(0.95, 0.95);
        root.Opacity = 0;
        Loaded += (_, _) =>
        {
            var fade = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(150));
            root.BeginAnimation(OpacityProperty, fade);
            var scaleX = new DoubleAnimation(0.95, 1, TimeSpan.FromMilliseconds(200))
            { EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut } };
            var scaleY = new DoubleAnimation(0.95, 1, TimeSpan.FromMilliseconds(200))
            { EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut } };
            ((ScaleTransform)root.RenderTransform).BeginAnimation(ScaleTransform.ScaleXProperty, scaleX);
            ((ScaleTransform)root.RenderTransform).BeginAnimation(ScaleTransform.ScaleYProperty, scaleY);
        };

        // ESC → 취소
        KeyDown += (_, e) =>
        {
            if (e.Key == Key.Escape) { _selectedResponse = ""; DialogResult = false; Close(); }
            if (e.Key == Key.Enter && !_customInput.IsFocused) { DialogResult = true; Close(); }
        };
    }

    private static Border? FindRadioCircle(Border optionBorder)
    {
        if (optionBorder.Child is StackPanel sp && sp.Children.Count > 0 && sp.Children[0] is Border outer
            && outer.Child is Border inner)
            return inner;
        return null;
    }

    /// <summary>에이전트 질문 다이얼로그를 표시합니다.</summary>
    /// <returns>사용자 응답 문자열. 취소 시 null.</returns>
    public static string? Show(string question, List<string> options, string defaultValue = "")
    {
        var dlg = new UserAskDialog(question, options, defaultValue);
        var result = dlg.ShowDialog();
        return result == true ? dlg.SelectedResponse : null;
    }
}
