using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace DansoriEQ.App.Controls;

public enum MascotKind { Sori, Dan }

/// <summary>Living mascot avatar: idle blink, talk mouth-flap, gentle float. Pure WPF (경로 A).</summary>
public partial class MascotAvatar : UserControl
{
    private BitmapImage _neutral = null!, _blink = null!, _talk = null!, _wink = null!;
    private readonly DispatcherTimer _blinkTimer = new();
    private readonly DispatcherTimer _talkTimer  = new() { Interval = TimeSpan.FromMilliseconds(140) };
    private readonly Random _rng = new();
    private bool _talking;
    private bool _talkPhase;

    public MascotAvatar()
    {
        InitializeComponent();
        LoadFrames(MascotKind.Sori);

        _blinkTimer.Tick += (_, __) => Blink();
        _talkTimer.Tick  += (_, __) =>
        {
            _talkPhase = !_talkPhase;
            AvaBrush.ImageSource = _talkPhase ? _talk : _neutral;
        };

        Loaded += (_, __) =>
        {
            ScheduleNextBlink();
            _blinkTimer.Start();
            StartFloat();
        };
        Unloaded += (_, __) => { _blinkTimer.Stop(); _talkTimer.Stop(); };
    }

    /// <summary>Which mascot to show.</summary>
    public MascotKind Kind
    {
        get => _kind;
        set { _kind = value; LoadFrames(value); }
    }
    private MascotKind _kind = MascotKind.Sori;

    private static BitmapImage Load(string file)
    {
        var img = new BitmapImage();
        img.BeginInit();
        img.UriSource = new Uri($"pack://application:,,,/Assets/Characters/{file}");
        img.CacheOption = BitmapCacheOption.OnLoad;
        img.EndInit();
        img.Freeze();
        return img;
    }

    private void LoadFrames(MascotKind kind)
    {
        string p = kind == MascotKind.Dan ? "dan" : "sori";
        _neutral = Load($"{p}_avatar_a_neutral.png");
        _blink   = Load($"{p}_avatar_b_blink.png");
        _talk    = Load($"{p}_avatar_c_talk.png");
        _wink    = Load($"{p}_avatar_d_wink.png");
        if (AvaBrush != null) AvaBrush.ImageSource = _neutral;
    }

    // ── blink ──
    private void ScheduleNextBlink()
        => _blinkTimer.Interval = TimeSpan.FromMilliseconds(_rng.Next(2800, 6200));

    private void Blink()
    {
        ScheduleNextBlink();
        if (_talking) return;                 // talk animation owns the frame while speaking
        AvaBrush.ImageSource = _blink;
        var revert = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(120) };
        revert.Tick += (s, e) =>
        {
            ((DispatcherTimer)s!).Stop();
            if (!_talking) AvaBrush.ImageSource = _neutral;
        };
        revert.Start();
    }

    // ── talk ──
    /// <summary>Start mouth-flap talk animation (call while AI is responding).</summary>
    public void StartTalking()
    {
        if (_talking) return;
        _talking = true;
        _talkPhase = false;
        _talkTimer.Start();
    }

    /// <summary>Stop talking and return to a neutral, smiling face.</summary>
    public void StopTalking()
    {
        _talking = false;
        _talkTimer.Stop();
        AvaBrush.ImageSource = _neutral;
    }

    // ── idle float ──
    private void StartFloat()
    {
        var anim = new DoubleAnimation
        {
            From = 0, To = -3, Duration = TimeSpan.FromMilliseconds(2200),
            AutoReverse = true, RepeatBehavior = RepeatBehavior.Forever,
            EasingFunction = new SineEase { EasingMode = EasingMode.EaseInOut }
        };
        Floater.BeginAnimation(TranslateTransform.YProperty, anim);
    }
}
