using Cirno.Scripts.Misc;
using Godot;

namespace Cirno.Scripts.Resources.Events;

[GlobalClass]
public partial class DialogueStartEvent : EventResource
{
    [Export] public StringName TimelineName = "timeline";
    private Node _dialogic;
    private GameManager _gameManager;
    private bool _isComplete = false;

    private DialogueSkipListener _listener;

    public override void Init(Node2D parent)
    {
        _gameManager = parent.GetGameManager();
        _dialogic = parent.GetNode("/root/Dialogic");
        _dialogic.ProcessMode = Node.ProcessModeEnum.Always;
    }

    public override void Start(Node2D parent)
    {
        if (GlobalState.Instance.SessionSettings.SkipDialogues)
        {
            DialogueEndAction();
            return;
        }
        
        CreateSkipListener(parent);
        
        Hud.Instance?.HideHud();
        
        _dialogic.Connect("timeline_ended", Callable.From(OnTimelineEnded));

        var dialogicNode =_dialogic.Call("start", TimelineName.ToString());
        ((Node)dialogicNode).ProcessMode = Node.ProcessModeEnum.Always;
        _gameManager.ChangeState(GameState.Dialogue);
    }

    private void CreateSkipListener(Node2D parent)
    {
        _listener = new DialogueSkipListener();
        parent.AddChild(_listener);
        _listener.ProcessMode = Node.ProcessModeEnum.Always;
        _listener.Skipped += ListenerOnSkipped;
    }

    private void ListenerOnSkipped()
    {
        _listener.Skipped -= ListenerOnSkipped;
        _listener.QueueFree();
        _dialogic.Call("end_timeline");
    }

    private void OnTimelineEnded()
    {
        Hud.Instance?.ShowHud();
        _gameManager.ChangeState(GameState.Playing);
        if (_dialogic.IsConnected("timeline_ended", Callable.From(OnTimelineEnded)))
        {
            _dialogic.Disconnect("timeline_ended", Callable.From(OnTimelineEnded));
        }

        DialogueEndAction();
    }

    private void DialogueEndAction()
    {
        _isComplete = true;
    }

    public override void UpdateEvent(double delta)
    {
    }

    public override bool IsComplete()
    {
        return _isComplete;
    }
}