using Cirno.Scripts.Actors;
using Cirno.Scripts.Resources;
using Godot;

namespace Cirno.Scripts.AttackPatterns;

[GlobalClass]
[Tool]
public partial class MovementPattern : AttackPattern
{
    [Export] public Vector2 relativeTargetPosition;
    [Export] public float moveDuration = 2f;
    [Export] public Tween.TransitionType transitionType = Tween.TransitionType.Linear;
    [Export] public Tween.EaseType easeType = Tween.EaseType.InOut;
    [Export] public AttackPattern shootingPattern;
    
    public override IPatternMachine MakeMachine(Node parent)
    {
        return new MovementPatternMachine(this, parent);
    }

    public class MovementPatternMachine(MovementPattern pattern, Node parent) : IPatternMachine
    {
        public Node Parent => parent;
        public MovementPattern Pattern { get; } = pattern;
        
        private IPatternMachine _machine;

        private Tween tween;
        private bool isComplete = false;
    
        protected IScriptHost Boss;
    
        public void Start()
        {
            if (parent is not IScriptHost boss)
                return;
        
            Boss = boss;
            tween = parent.CreateTween();
            isComplete = false;
            
            
            Vector2 targetPosition = (Boss?.HomePosition ?? boss.ParentObject.GlobalPosition) + Pattern.relativeTargetPosition;
        
            tween.TweenProperty(boss.ParentObject, "position", targetPosition, Pattern.moveDuration)
                .SetTrans(Pattern.transitionType)
                .SetEase(Pattern.easeType)
                .Finished += () => isComplete = true;

            if (Pattern.shootingPattern != null && !Pattern.WaitForCompletion)
            {
                _machine = Pattern.shootingPattern.MakeMachine(parent);
                _machine.Start();
            }
        }

        public void UpdatePattern(double delta)
        {
            if (_machine is not null && !Pattern.WaitForCompletion)
            {
                _machine.UpdatePattern(delta);
                //shootingPattern.UpdatePattern(delta);
            }
        }

        public bool IsComplete()
        {
            if (Pattern.WaitForCompletion && _machine is not null)
                return isComplete && _machine.IsComplete();
            return isComplete;
        }
    }
}