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

namespace HowToChooseTokenCode
{
	public class DialogueWriter : MonoBehaviour, IReflectable
    {
		private readonly float LetterInterval = 0.04f;

		[SerializeField]
        private TextMeshProUGUI speakerText;
        [SerializeField]
        private TextMeshProUGUI dialogueText;
        [SerializeField]
        private CharacterAnimator characterAnimator;

        [CommandMethod("write dialogue async")]
        [Category("Dialogue")]
        [Description("Show a dialogue on the screen.")]
        [Snippet("{${1:speaker}}")]
        [Snippet("{${2:dialogue}}")]
        public async UniTask WriteDialogueAsync(string speaker,  string dialogue, CancellationToken cancellationToken)
        {
            speakerText.text = speaker;
            dialogueText.maxVisibleCharacters = 0;
            dialogueText.text = dialogue;
			try
            {
                foreach (var letter in dialogue)
                {
                    dialogueText.maxVisibleCharacters++;
					if (!char.IsWhiteSpace(letter))
						await UniTask.Delay(TimeSpan.FromSeconds(LetterInterval), cancellationToken: cancellationToken);
				}
            }
            finally
            {
                dialogueText.maxVisibleCharacters = int.MaxValue;
            }
        }

        [CommandMethod("write dialogue and image async")]
        [Category("Dialogue")]
        [Description("Show a dialogue on the screren.")]
        [Description("Also, change the character icon.")]
        [DialogueSnippet("Change the icon to {${1:image}}")]
		[Snippet("{${1:speaker}}")]
		[Snippet("{${2:dialogue}}")]
        [Snippet("Change the icon to {${3:image}}")]
		public async UniTask WriteDialogueAndChangeImageAsync(string speaker, string dialogue, Sprite sprite, CancellationToken cancellationToken)
        {
            await UniTask.WhenAll(
                WriteDialogueAsync(speaker, dialogue, cancellationToken),
                characterAnimator.ChangeCharacterImageAsync(sprite, cancellationToken));
        }
    }
}