using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;

namespace AxCopilot.Views;

/// <summary>
/// 에이전트 실행 계획을 상세히 보여주는 별도 창.
/// - 항목 기본 접힘 / 클릭으로 펼침
/// - 모두 열기 / 모두 닫기 툴바
/// - 사방 가장자리 드래그 리사이즈
/// - 항목 드래그로 순서 변경
/// </summary>
internal sealed partial class PlanViewerWindow : Window
{
    // ── Win32 Resize ──
    [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
    private const int WM_NCHITTEST = 0x0084;
    private const int HTLEFT = 10, HTRIGHT = 11, HTTOP = 12, HTTOPLEFT = 13,
        HTTOPRIGHT = 14, HTBOTTOM = 15, HTBOTTOMLEFT = 16, HTBOTTOMRIGHT = 17;
    private const int ResizeGrip = 12; // 사방 12px 영역에서 리사이즈 가능

    private const string DragDataFormat = "PlanStepIndex";

    private readonly StackPanel _stepsPanel;
    private readonly ScrollViewer _scrollViewer;
    private readonly StackPanel _btnPanel;
    private readonly Border _statusBar;
    private readonly TextBlock _statusText;
    private readonly TextBlock _progressText;

    // 펼침 상태 관리
    private readonly HashSet<int> _expandedSteps = new();

    // 드래그 상태
    private int _dragSourceIndex = -1;
    private Point _dragStartPoint;

    private TaskCompletionSource<string?>? _tcs;
    private string _planText = "";
    private List<string> _steps = new();
    private int _currentStep = -1;
    private bool _isExecuting;

    public PlanViewerWindow()
    {
        Width = 640;
        Height = 520;
        MinWidth = 480;
        MinHeight = 360;
        WindowStartupLocation = WindowStartupLocation.CenterScreen;
        WindowStyle = WindowStyle.None;
        AllowsTransparency = true;
        Background = Brushes.Transparent;
        ResizeMode = ResizeMode.CanResize; // WndProc로 직접 처리
        ShowInTaskbar = false;

        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 root = new Border
        {
            Background = bgBrush,
            CornerRadius = new CornerRadius(14),
            BorderBrush = borderBrush,
            BorderThickness = new Thickness(1),
            Effect = new DropShadowEffect { BlurRadius = 20, ShadowDepth = 4, Opacity = 0.35, Color = Colors.Black },
        };

        var mainGrid = new Grid();
        mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });                            // 0: 타이틀 바
        mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });                            // 1: 상태 바
        mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });                            // 2: 툴바 (모두 열기/닫기)
        mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });       // 3: 단계 목록
        mainGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });                            // 4: 하단 버튼

        // ── 타이틀 바 ──
        var titleBar = new Grid { Background = Brushes.Transparent, Margin = new Thickness(20, 14, 12, 0) };
        titleBar.MouseLeftButtonDown += TitleBar_MouseLeftButtonDown;

        var titleSp = new StackPanel { Orientation = Orientation.Horizontal };
        titleSp.Children.Add(new TextBlock
        {
            Text = "\uE9D2", FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize = 18, Foreground = accentBrush, VerticalAlignment = VerticalAlignment.Center,
            Margin = new Thickness(0, 0, 10, 0),
        });
        titleSp.Children.Add(new TextBlock
        {
            Text = "실행 계획", FontSize = 16, FontWeight = FontWeights.Bold,
            Foreground = primaryText, VerticalAlignment = VerticalAlignment.Center,
        });
        titleBar.Children.Add(titleSp);

        var closeBtn = new Border
        {
            Width = 32, Height = 32, CornerRadius = new CornerRadius(8),
            Background = Brushes.Transparent, Cursor = Cursors.Hand,
            HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center,
            Child = new TextBlock
            {
                Text = "\uE8BB", FontFamily = ThemeResourceHelper.SegoeMdl2,
                FontSize = 12, Foreground = secondaryText,
                HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center,
            },
        };
        closeBtn.MouseEnter += (s, _) => ((Border)s).Background = new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
        closeBtn.MouseLeave += (s, _) => ((Border)s).Background = Brushes.Transparent;
        closeBtn.MouseLeftButtonUp += (_, _) => Hide();
        titleBar.Children.Add(closeBtn);
        Grid.SetRow(titleBar, 0);
        mainGrid.Children.Add(titleBar);

        // ── 상태 바 (진행률) ──
        _statusBar = new Border
        {
            Visibility = Visibility.Collapsed,
            Margin = new Thickness(20, 8, 20, 0),
            Padding = new Thickness(12, 6, 12, 6),
            CornerRadius = new CornerRadius(8),
            Background = new SolidColorBrush(Color.FromArgb(0x15,
                ((SolidColorBrush)accentBrush).Color.R,
                ((SolidColorBrush)accentBrush).Color.G,
                ((SolidColorBrush)accentBrush).Color.B)),
        };
        var statusGrid = new Grid();
        _statusText = new TextBlock { Text = "실행 중...", FontSize = 12, Foreground = accentBrush, VerticalAlignment = VerticalAlignment.Center };
        statusGrid.Children.Add(_statusText);
        _progressText = new TextBlock
        {
            Text = "", FontSize = 12, Foreground = secondaryText,
            HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center,
        };
        statusGrid.Children.Add(_progressText);
        _statusBar.Child = statusGrid;
        Grid.SetRow(_statusBar, 1);
        mainGrid.Children.Add(_statusBar);

        // ── 툴바: 모두 열기 / 모두 닫기 ──
        var hoverBgTb = Application.Current.TryFindResource("ItemHoverBackground") as Brush
                        ?? new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
        var toolBar = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            HorizontalAlignment = HorizontalAlignment.Right,
            Margin = new Thickness(20, 6, 20, 0),
        };

        var expandAllBtn = MakeToolbarButton("\uE70D", "모두 열기", secondaryText, hoverBgTb);
        expandAllBtn.MouseLeftButtonUp += (_, _) =>
        {
            for (int i = 0; i < _steps.Count; i++) _expandedSteps.Add(i);
            RenderSteps();
        };
        toolBar.Children.Add(expandAllBtn);

        var collapseAllBtn = MakeToolbarButton("\uE70E", "모두 닫기", secondaryText, hoverBgTb);
        collapseAllBtn.MouseLeftButtonUp += (_, _) => { _expandedSteps.Clear(); RenderSteps(); };
        toolBar.Children.Add(collapseAllBtn);

        Grid.SetRow(toolBar, 2);
        mainGrid.Children.Add(toolBar);

        // ── 컨텐츠: 단계 목록 ──
        _scrollViewer = new ScrollViewer
        {
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
            Margin = new Thickness(16, 6, 16, 0),
            Padding = new Thickness(4),
        };
        _stepsPanel = new StackPanel();
        _scrollViewer.Content = _stepsPanel;
        Grid.SetRow(_scrollViewer, 3);
        mainGrid.Children.Add(_scrollViewer);

        // ── 하단 버튼 패널 ──
        _btnPanel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            HorizontalAlignment = HorizontalAlignment.Center,
            Margin = new Thickness(20, 12, 20, 16),
        };
        Grid.SetRow(_btnPanel, 4);
        mainGrid.Children.Add(_btnPanel);

        root.Child = mainGrid;
        Content = root;

        // Win32 Resize 훅
        SourceInitialized += (_, _) =>
        {
            var hwnd = new WindowInteropHelper(this).Handle;
            var src = HwndSource.FromHwnd(hwnd);
            src?.AddHook(WndProc);
        };
    }

    // ════════════════════════════════════════════════════════════
    // 툴바 버튼 팩토리
    // ════════════════════════════════════════════════════════════

    private static Border MakeToolbarButton(string icon, string label, Brush fg, Brush hoverBg)
    {
        var btn = new Border
        {
            CornerRadius = new CornerRadius(6),
            Padding = new Thickness(8, 3, 8, 3),
            Margin = new Thickness(0, 0, 4, 0),
            Background = Brushes.Transparent,
            Cursor = Cursors.Hand,
        };
        var sp = new StackPanel { Orientation = Orientation.Horizontal };
        sp.Children.Add(new TextBlock
        {
            Text = icon, FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize = 9, Foreground = fg,
            VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0, 0, 4, 0),
        });
        sp.Children.Add(new TextBlock { Text = label, FontSize = 11.5, Foreground = fg });
        btn.Child = sp;
        btn.MouseEnter += (s, _) => ((Border)s).Background = hoverBg;
        btn.MouseLeave += (s, _) => ((Border)s).Background = Brushes.Transparent;
        return btn;
    }

    // ════════════════════════════════════════════════════════════
    // 창 이동 / 리사이즈
    // ════════════════════════════════════════════════════════════

    private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ClickCount == 2) return;
        try { DragMove(); } catch (Exception) { }
    }

    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)));
            var w = ActualWidth;
            var h = ActualHeight;

            int hit = 0;
            if      (pt.X < ResizeGrip && pt.Y < ResizeGrip)         hit = HTTOPLEFT;
            else if (pt.X > w - ResizeGrip && pt.Y < ResizeGrip)     hit = HTTOPRIGHT;
            else if (pt.X < ResizeGrip && pt.Y > h - ResizeGrip)     hit = HTBOTTOMLEFT;
            else if (pt.X > w - ResizeGrip && pt.Y > h - ResizeGrip) hit = HTBOTTOMRIGHT;
            else if (pt.X < ResizeGrip)         hit = HTLEFT;
            else if (pt.X > w - ResizeGrip)     hit = HTRIGHT;
            else if (pt.Y < ResizeGrip)         hit = HTTOP;
            else if (pt.Y > h - ResizeGrip)     hit = HTBOTTOM;

            if (hit != 0) { handled = true; return (IntPtr)hit; }
        }
        return IntPtr.Zero;
    }

    // ════════════════════════════════════════════════════════════
    // 공개 API
    // ════════════════════════════════════════════════════════════

    public Task<string?> ShowPlanAsync(string planText, List<string> steps, TaskCompletionSource<string?> tcs)
    {
        _planText = planText;
        _steps = steps;
        _tcs = tcs;
        _currentStep = -1;
        _isExecuting = false;
        _expandedSteps.Clear(); // 새 계획 표시 시 모두 접힌 상태로 시작

        RenderSteps();
        BuildApprovalButtons();
        _statusBar.Visibility = Visibility.Collapsed;

        Show();
        Activate();
        return tcs.Task;
    }

    public void SwitchToExecutionMode()
    {
        _isExecuting = true;
        _statusBar.Visibility = Visibility.Visible;
        _statusText.Text = "▶ 계획 실행 중...";
        _progressText.Text = $"0 / {_steps.Count}";
        BuildExecutionButtons();
    }

    public void UpdateCurrentStep(int stepIndex)
    {
        if (stepIndex < 0 || stepIndex >= _steps.Count) return;
        _currentStep = stepIndex;
        _progressText.Text = $"{stepIndex + 1} / {_steps.Count}";
        _expandedSteps.Add(stepIndex); // 현재 실행 중인 단계는 자동 펼침
        RenderSteps();
    }

    public void MarkComplete()
    {
        _isExecuting = false;
        _statusText.Text = "✓ 계획 실행 완료";
        _statusText.Foreground = new SolidColorBrush(Color.FromRgb(0x10, 0xB9, 0x81));
        _progressText.Text = $"{_steps.Count} / {_steps.Count}";
        _currentStep = _steps.Count;
        RenderSteps();
        BuildCloseButton();
    }

    public string PlanText => _planText;
    public List<string> Steps => _steps;
}
