using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using ScenarioFlow;
using ScenarioFlow.Scripts.SFText;
using ScenarioFlow.Tasks;
using System.Threading;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace HowToChooseTokenCode
{
	public class ScenarioBranchMaker : MonoBehaviour, IReflectable
	{
		[SerializeField]
		private Button button1;
		[SerializeField]
		private Button button2;

		public ILabelOpener LabelOpener { get; set; }

		private void Awake()
		{
			button1.gameObject.SetActive(false);
			button2.gameObject.SetActive(false);
		}

		[CommandMethod("show two selections async")]
		[Category("Branch")]
		[Description("Show two selections two the player.")]
		[Description("Move on to one of specified labels that correspondes to the answer.")]
		[Snippet("{${1:selection1}}")]
		[Snippet("--- Jump to {${2:label1}}")]
		[Snippet("{${3:selection2}}")]
		[Snippet("--- Jump to {${4:label2}}")]
		public async UniTask ShowTwoSelectionsAsync(string selection1, string label1, string selection2, string label2, CancellationToken cancellationToken)
		{
			button1.gameObject.SetActive(true);
			button2.gameObject.SetActive(true);
			button1.GetComponentInChildren<TextMeshProUGUI>().text = selection1;
			button2.GetComponentInChildren<TextMeshProUGUI>().text = selection2;
			try
			{
				var answerIndex = await UniTask.WhenAny(WaitUntilClicked(button1, cancellationToken), WaitUntilClicked(button2, cancellationToken));
				var targetLabel = answerIndex == 0 ? label1 : label2;
				LabelOpener.OpenLabel(targetLabel);
			}
			finally
			{
				button1.gameObject.SetActive(false);
				button2.gameObject.SetActive(false);
			}
		}

		[CommandMethod("jump to label")]
		[Category("Branch")]
		[Description("Move on to a specified label.")]
		[Snippet("Jump to {${1:label}}")]
		public void JumpToLabel(string label)
		{
			LabelOpener.OpenLabel(label);
		}

		private UniTask WaitUntilClicked(Button button, CancellationToken cancellationToken)
		{
			return button.OnClickAsAsyncEnumerable(cancellationToken: cancellationToken)
				.FirstOrDefaultAsync(cancellationToken: cancellationToken);
		}
	}
}