using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using AxCopilot.Services;

namespace AxCopilot.Views;

/// <summary>
/// 에이전트 파일 수정 시 변경 전/후 diff를 보여주는 패널.
/// DiffService의 결과를 색상 하이라이트로 렌더링하고
/// Accept/Reject 버튼으로 변경 승인/취소를 지원합니다.
/// </summary>
public class DiffViewerPanel : Border
{
    private readonly string _filePath;
    private readonly string _oldContent;
    private readonly string _newContent;
    private readonly List<DiffService.DiffLine> _diffLines;

    /// <summary>사용자가 Accept를 눌렀을 때 발생합니다.</summary>
    public event EventHandler? Accepted;

    /// <summary>사용자가 Reject를 눌렀을 때 발생합니다.</summary>
    public event EventHandler? Rejected;

    public DiffViewerPanel(string filePath, string oldContent, string newContent)
    {
        _filePath = filePath;
        _oldContent = oldContent;
        _newContent = newContent;
        _diffLines = DiffService.ComputeDiff(oldContent, newContent);

        CornerRadius = new CornerRadius(10);
        Background = new SolidColorBrush(Color.FromRgb(0xFA, 0xFA, 0xFF));
        BorderBrush = new SolidColorBrush(Color.FromRgb(0xE0, 0xE0, 0xEC));
        BorderThickness = new Thickness(1);
        Padding = new Thickness(0);
        Margin = new Thickness(0, 8, 0, 8);

        Child = BuildContent();
    }

    private UIElement BuildContent()
    {
        var mainStack = new StackPanel();

        // 헤더
        var header = new Border
        {
            Background = new SolidColorBrush(Color.FromRgb(0xF0, 0xF2, 0xFF)),
            CornerRadius = new CornerRadius(10, 10, 0, 0),
            Padding = new Thickness(14, 10, 14, 10),
        };
        var headerGrid = new Grid();
        headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

        var summary = DiffService.GetSummary(_diffLines);
        var titlePanel = new StackPanel { Orientation = Orientation.Horizontal };
        titlePanel.Children.Add(new TextBlock
        {
            Text = "\uE89A",
            FontFamily = ThemeResourceHelper.SegoeMdl2,
            FontSize = 13, Foreground = new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC)),
            VerticalAlignment = VerticalAlignment.Center,
            Margin = new Thickness(0, 0, 8, 0),
        });
        titlePanel.Children.Add(new TextBlock
        {
            Text = System.IO.Path.GetFileName(_filePath),
            FontSize = 13, FontWeight = FontWeights.SemiBold,
            Foreground = new SolidColorBrush(Color.FromRgb(0x1A, 0x1B, 0x2E)),
            VerticalAlignment = VerticalAlignment.Center,
        });
        titlePanel.Children.Add(new TextBlock
        {
            Text = $"  ·  {summary}",
            FontSize = 11,
            Foreground = new SolidColorBrush(Color.FromRgb(0x88, 0x88, 0xAA)),
            VerticalAlignment = VerticalAlignment.Center,
        });
        Grid.SetColumn(titlePanel, 0);
        headerGrid.Children.Add(titlePanel);

        // Accept / Reject 버튼
        var btnPanel = new StackPanel { Orientation = Orientation.Horizontal };
        var acceptBtn = CreateButton("적용", Color.FromRgb(0x10, 0x7C, 0x10), Colors.White);
        acceptBtn.Click += (_, _) => Accepted?.Invoke(this, EventArgs.Empty);
        btnPanel.Children.Add(acceptBtn);

        var rejectBtn = CreateButton("취소", Colors.Transparent, Color.FromRgb(0xC5, 0x0F, 0x1F));
        rejectBtn.Click += (_, _) => Rejected?.Invoke(this, EventArgs.Empty);
        btnPanel.Children.Add(rejectBtn);

        Grid.SetColumn(btnPanel, 1);
        headerGrid.Children.Add(btnPanel);

        header.Child = headerGrid;
        mainStack.Children.Add(header);

        // Diff 내용
        var scrollViewer = new ScrollViewer
        {
            MaxHeight = 300,
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
            HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
        };

        var diffStack = new StackPanel { Margin = new Thickness(0) };

        foreach (var line in _diffLines)
        {
            var (bg, fg, prefix) = line.Type switch
            {
                DiffService.DiffType.Added => (
                    Color.FromRgb(0xE6, 0xFF, 0xED),
                    Color.FromRgb(0x16, 0x6C, 0x34),
                    "+"),
                DiffService.DiffType.Removed => (
                    Color.FromRgb(0xFF, 0xEB, 0xE9),
                    Color.FromRgb(0xCF, 0x22, 0x2E),
                    "-"),
                _ => (
                    Color.FromRgb(0xFF, 0xFF, 0xFF),
                    Color.FromRgb(0x66, 0x66, 0x88),
                    " ")
            };

            var lineNo = line.OldLineNo?.ToString() ?? "";
            var newLineNo = line.NewLineNo?.ToString() ?? "";

            var linePanel = new Border
            {
                Background = new SolidColorBrush(bg),
                Padding = new Thickness(8, 1, 8, 1),
            };

            var lineGrid = new Grid();
            lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(36) }); // old line
            lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(36) }); // new line
            lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(16) }); // prefix
            lineGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); // content

            var oldLineText = new TextBlock
            {
                Text = lineNo, FontSize = 10, FontFamily = ThemeResourceHelper.Consolas,
                Foreground = new SolidColorBrush(Color.FromRgb(0xAA, 0xAA, 0xCC)),
                HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 0, 4, 0),
            };
            Grid.SetColumn(oldLineText, 0);
            lineGrid.Children.Add(oldLineText);

            var newLineText = new TextBlock
            {
                Text = newLineNo, FontSize = 10, FontFamily = ThemeResourceHelper.Consolas,
                Foreground = new SolidColorBrush(Color.FromRgb(0xAA, 0xAA, 0xCC)),
                HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 0, 4, 0),
            };
            Grid.SetColumn(newLineText, 1);
            lineGrid.Children.Add(newLineText);

            var prefixText = new TextBlock
            {
                Text = prefix, FontSize = 11, FontFamily = ThemeResourceHelper.Consolas,
                Foreground = new SolidColorBrush(fg), FontWeight = FontWeights.Bold,
            };
            Grid.SetColumn(prefixText, 2);
            lineGrid.Children.Add(prefixText);

            var contentText = new TextBlock
            {
                Text = line.Content, FontSize = 11, FontFamily = ThemeResourceHelper.Consolas,
                Foreground = new SolidColorBrush(fg),
                TextWrapping = TextWrapping.NoWrap,
            };
            Grid.SetColumn(contentText, 3);
            lineGrid.Children.Add(contentText);

            linePanel.Child = lineGrid;
            diffStack.Children.Add(linePanel);
        }

        scrollViewer.Content = diffStack;
        mainStack.Children.Add(scrollViewer);

        return mainStack;
    }

    private static Button CreateButton(string text, Color bg, Color fg)
    {
        var btn = new Button { Cursor = System.Windows.Input.Cursors.Hand, Margin = new Thickness(4, 0, 0, 0) };
        var template = new ControlTemplate(typeof(Button));
        var bdFactory = new FrameworkElementFactory(typeof(Border));
        bdFactory.SetValue(Border.BackgroundProperty, new SolidColorBrush(bg));
        bdFactory.SetValue(Border.CornerRadiusProperty, new CornerRadius(6));
        bdFactory.SetValue(Border.PaddingProperty, new Thickness(12, 5, 12, 5));
        if (bg == Colors.Transparent)
        {
            bdFactory.SetValue(Border.BorderBrushProperty, new SolidColorBrush(fg));
            bdFactory.SetValue(Border.BorderThicknessProperty, new Thickness(1));
        }
        var cpFactory = new FrameworkElementFactory(typeof(ContentPresenter));
        cpFactory.SetValue(ContentPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
        bdFactory.AppendChild(cpFactory);
        template.VisualTree = bdFactory;
        btn.Template = template;
        btn.Content = new TextBlock { Text = text, FontSize = 11, Foreground = new SolidColorBrush(fg), FontWeight = FontWeights.SemiBold };
        return btn;
    }
}
