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

namespace AxCopilot.Views;

public partial class ChatWindow
{
    // ─── 애니메이션 + 체크 헬퍼 ─────────────────────────────────────────

    // ─── 커스텀 체크 아이콘 (모든 팝업 메뉴 공통) ─────────────────────────

    /// <summary>커스텀 체크/미선택 아이콘을 생성합니다. Path 도형 기반, 선택 시 스케일 바운스 애니메이션.</summary>
    /// <summary>현재 테마의 체크 스타일을 반환합니다.</summary>
    private string GetCheckStyle()
    {
        var theme = (_settings.Settings.Launcher.Theme ?? "system").ToLowerInvariant();
        return theme switch
        {
            "dark" or "system" => "circle",       // 원 + 체크마크, 바운스
            "oled"             => "glow",          // 네온 글로우 원, 페이드인
            "light"            => "roundrect",     // 둥근 사각형, 슬라이드인
            "nord"             => "diamond",       // 다이아몬드(마름모), 스무스 스케일
            "catppuccin"       => "pill",          // 필 모양, 스프링 바운스
            "monokai"          => "square",        // 정사각형, 퀵 팝
            "sepia"            => "stamp",         // 도장 스타일 원, 회전 등장
            "alfred"           => "minimal",       // 미니멀 원, 우아한 페이드
            "alfredlight"      => "minimal",       // 미니멀 원, 우아한 페이드
            _                  => "circle",
        };
    }

    private FrameworkElement CreateCheckIcon(bool isChecked, Brush? accentBrush = null)
    {
        var accent = accentBrush ?? ThemeResourceHelper.Accent(this);

        // 심플 V 체크 — 선택 시 컬러 V, 미선택 시 빈 공간
        if (isChecked)
        {
            return CreateSimpleCheck(accent, 14);
        }

        // 미선택: 동일 크기 빈 공간 (정렬 유지)
        return new System.Windows.Shapes.Rectangle
        {
            Width = 14, Height = 14,
            Fill = Brushes.Transparent,
            Margin = new Thickness(0, 0, 10, 0),
        };
    }

    /// <summary>ScaleTransform 바운스/스케일 애니메이션 헬퍼.</summary>
    private static void AnimateScale(FrameworkElement el, double from, double to, int ms, IEasingFunction ease)
    {
        if (el.RenderTransform is TransformGroup tg)
        {
            var st = tg.Children.OfType<ScaleTransform>().FirstOrDefault();
            if (st != null)
            {
                var anim = new DoubleAnimation(from, to, TimeSpan.FromMilliseconds(ms)) { EasingFunction = ease };
                st.BeginAnimation(ScaleTransform.ScaleXProperty, anim);
                st.BeginAnimation(ScaleTransform.ScaleYProperty, anim);
                return;
            }
        }
        if (el.RenderTransform is ScaleTransform scale)
        {
            var anim = new DoubleAnimation(from, to, TimeSpan.FromMilliseconds(ms)) { EasingFunction = ease };
            scale.BeginAnimation(ScaleTransform.ScaleXProperty, anim);
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, anim);
        }
    }

    /// <summary>마우스 오버 시 살짝 확대 + 복귀하는 호버 애니메이션을 적용합니다.</summary>
    /// <summary>
    /// 마우스 오버 시 살짝 확대하는 호버 애니메이션.
    /// 주의: 인접 요소(탭 버튼, 가로 나열 메뉴 등)에는 사용 금지 — 확대 시 이웃 요소를 가립니다.
    /// 독립적 공간이 있는 버튼에만 적용하세요.
    /// </summary>
    private static void ApplyHoverScaleAnimation(FrameworkElement element, double hoverScale = 1.08)
    {
        // Loaded 이벤트에서 실행해야 XAML Style의 봉인된 Transform을 안전하게 교체 가능
        void EnsureTransform()
        {
            element.RenderTransformOrigin = new Point(0.5, 0.5);
            // 봉인(frozen)된 Transform이면 새로 생성하여 교체
            if (element.RenderTransform is not ScaleTransform || element.RenderTransform.IsFrozen)
                element.RenderTransform = new ScaleTransform(1, 1);
        }

        element.Loaded += (_, _) => EnsureTransform();

        element.MouseEnter += (_, _) =>
        {
            EnsureTransform();
            var st = (ScaleTransform)element.RenderTransform;
            var grow = new DoubleAnimation(hoverScale, TimeSpan.FromMilliseconds(150))
            { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut } };
            st.BeginAnimation(ScaleTransform.ScaleXProperty, grow);
            st.BeginAnimation(ScaleTransform.ScaleYProperty, grow);
        };
        element.MouseLeave += (_, _) =>
        {
            EnsureTransform();
            var st = (ScaleTransform)element.RenderTransform;
            var shrink = new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(200))
            { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut } };
            st.BeginAnimation(ScaleTransform.ScaleXProperty, shrink);
            st.BeginAnimation(ScaleTransform.ScaleYProperty, shrink);
        };
    }

    /// <summary>마우스 오버 시 텍스트가 살짝 튀어오르는 바운스 애니메이션을 적용합니다.</summary>
    /// <summary>
    /// 마우스 오버 시 텍스트가 살짝 튀어오르는 바운스 애니메이션.
    /// Scale과 달리 크기가 변하지 않아 인접 요소를 가리지 않습니다.
    /// </summary>
    private static void ApplyHoverBounceAnimation(FrameworkElement element, double bounceY = -2.5)
    {
        void EnsureTransform()
        {
            if (element.RenderTransform is not TranslateTransform || element.RenderTransform.IsFrozen)
                element.RenderTransform = new TranslateTransform(0, 0);
        }

        element.Loaded += (_, _) => EnsureTransform();

        element.MouseEnter += (_, _) =>
        {
            EnsureTransform();
            var tt = (TranslateTransform)element.RenderTransform;
            tt.BeginAnimation(TranslateTransform.YProperty,
                new DoubleAnimation(bounceY, TimeSpan.FromMilliseconds(200))
                { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut } });
        };
        element.MouseLeave += (_, _) =>
        {
            EnsureTransform();
            var tt = (TranslateTransform)element.RenderTransform;
            tt.BeginAnimation(TranslateTransform.YProperty,
                new DoubleAnimation(0, TimeSpan.FromMilliseconds(250))
                { EasingFunction = new ElasticEase { EasingMode = EasingMode.EaseOut, Oscillations = 1, Springiness = 10 } });
        };
    }

    /// <summary>심플한 V 체크 아이콘을 생성합니다 (디자인 통일용).</summary>
    private static FrameworkElement CreateSimpleCheck(Brush color, double size = 14)
    {
        return new System.Windows.Shapes.Path
        {
            Data = Geometry.Parse($"M {size * 0.15} {size * 0.5} L {size * 0.4} {size * 0.75} L {size * 0.85} {size * 0.28}"),
            Stroke = color,
            StrokeThickness = 2,
            StrokeStartLineCap = PenLineCap.Round,
            StrokeEndLineCap = PenLineCap.Round,
            StrokeLineJoin = PenLineJoin.Round,
            Width = size,
            Height = size,
            Margin = new Thickness(0, 0, 10, 0),
            VerticalAlignment = VerticalAlignment.Center,
        };
    }

    /// <summary>팝업 메뉴 항목에 호버 배경색 + 미세 확대 효과를 적용합니다.</summary>
    private static void ApplyMenuItemHover(Border item)
    {
        var originalBg = item.Background?.Clone() ?? Brushes.Transparent;
        if (originalBg.CanFreeze) originalBg.Freeze();
        item.RenderTransformOrigin = new Point(0.5, 0.5);
        item.RenderTransform = new ScaleTransform(1, 1);
        item.MouseEnter += (s, _) =>
        {
            if (s is Border b)
            {
                // 원래 배경이 투명이면 반투명 흰색, 아니면 밝기 변경
                if (originalBg is SolidColorBrush scb && scb.Color.A > 0x20)
                    b.Opacity = 0.85;
                else
                    b.Background = new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
            }
            var st = item.RenderTransform as ScaleTransform;
            st?.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(1.02, TimeSpan.FromMilliseconds(120)));
            st?.BeginAnimation(ScaleTransform.ScaleYProperty, new DoubleAnimation(1.02, TimeSpan.FromMilliseconds(120)));
        };
        item.MouseLeave += (s, _) =>
        {
            if (s is Border b)
            {
                b.Opacity = 1.0;
                b.Background = originalBg;
            }
            var st = item.RenderTransform as ScaleTransform;
            st?.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(150)));
            st?.BeginAnimation(ScaleTransform.ScaleYProperty, new DoubleAnimation(1.0, TimeSpan.FromMilliseconds(150)));
        };
    }
}
