using DG.Tweening;
using System;
using UnityEngine;
using XGame.Framework.Interfaces;
using XGame.Framework.Time;

namespace FL.Battle.Actions
{
    /// <summary>
    /// 抛物线移动
    /// 中心点位置固定的贝塞尔曲线
    /// </summary>
    internal class MoveParabolaAction : IAction, IPauseable, ITimeScalable
    {
        public MoveActionArgs args;
        private Tween _tween;
        private bool _paused;
        float ITimeScalable.TimeScale
        {
            get => _tween?.timeScale ?? 1;
            set
            {
                if (_tween == null)
                {
                    return;
                }
                _tween.timeScale = value;
            }
        }
        void IReference.Clear()
        {
            args = default;
            _tween?.Kill();
            _tween = null;
            _paused = false;
        }

        public void Start(Transform transform)
        {
            transform.position = args.from;
            var totalTime = args.duration * 0.001f;
            var center = Vector3.Lerp(args.from, args.to, 0.5f);
            // z轴向相机偏移
            center.z -= 8;
            _tween = DOTween.To(() => 0, (t) =>
            {
                var tNormal = t / totalTime;
                var pos = args.from.BezierPoint(center, args.to, tNormal);
                transform.position = pos;
                args.onUpdate.SafeInvoke(pos);
            }, totalTime, totalTime);
            if (args.delay > 0)
            {
                _tween.SetDelay(args.delay * 0.001f);
            }
            _tween.SetEase(args.ease == Ease.Unset ? Ease.OutQuad : args.ease);
            _tween.onComplete += () =>
            {
                var callback = args.onComplete;
                _tween = null;
                args = default;
                callback.SafeInvoke();
            };
        }
        void IPauseable.Pause()
        {
            if (_tween == null || _paused)
            {
                return;
            }
            _paused = true;
            _tween.Pause();
        }
        void IPauseable.Resume()
        {
            if (_paused)
            {
                _paused = false;
                _tween?.Play();
            }
        }
    }
}
