using System;
using System.Text;
using UniRx;
using UnityEngine;
using UnityEngine.UI;


public class HarvestedAdditionView : MonoBehaviour
{
    private static readonly int Add = Animator.StringToHash("Add");
    private static readonly int Appear = Animator.StringToHash("Appear");
    private static readonly int Disappear = Animator.StringToHash("Disappear");
    private static readonly int Wait = Animator.StringToHash("Wait");
    
    [SerializeField] private Animator counterAnimator;
    [SerializeField] private TextWithCountUpInt counter;
    [Tooltip("揺れる頻度")]
    [SerializeField] private float triggerThrottle = .1f;
    [Tooltip("カウントアップ時間")]
    [SerializeField] private float countDuration = .4f;
    [Tooltip("コーンが来なくなってから待つ時間")]
    [SerializeField] private float waitDisappeared = 2f;
    [NonSerialized] public bool IsStopDisapper;
    private static readonly string harvestedCountFormat = "＋{0}";
    private static readonly string hasCountFormat = "{0}";
    private readonly Subject<Unit> playEffectObserve = new Subject<Unit>();
    private bool flag;
    private int latestCount;

    public IObservable<int> EndObservable => endObservable;
    private readonly Subject<int> endObservable = new Subject<int>();
    private Coroutine disapperCoroutine;

    private void Start()
    {
        playEffectObserve.AddTo(this);
        playEffectObserve
            .ThrottleFirst(TimeSpan.FromSeconds(triggerThrottle))
            .Subscribe(_ =>
            {
                transform.SetLocalScale(1);
                this.SafeStopCoroutine(disapperCoroutine);
                if (flag)
                {
                    counterAnimator.SetTrigger(Appear);
                }
                else
                {
                    counterAnimator.SetTrigger(Add);
                }
                flag = false;
            }).AddTo(this);
        // playEffectObserveが来なくなって0.15sで揺らすのを止める
        playEffectObserve
            .Throttle(TimeSpan.FromSeconds(.15f))
            .Subscribe(_ =>
            {
                counterAnimator.ResetTrigger(Add);
                counterAnimator.SetTrigger(Wait);
            }).AddTo(this);
        playEffectObserve
            .Throttle(TimeSpan.FromSeconds(waitDisappeared))
            .Where(_ => !IsStopDisapper)
            .Subscribe(_ =>
            {
                endObservable.OnNext(latestCount);
                SetHarvestedCount(0);
                disapperCoroutine = this.CallWaitForSeconds(countDuration, () =>
                {
                    Reset();
                    counterAnimator.SetTrigger(Disappear);
                });
            }).AddTo(this);
    }
    
    public void Initialize(int count)
    {
        transform.SetLocalScale(0);
        Reset();
    }

    private void Reset()
    {
        counter.ChangeValue(hasCountFormat, 0);
        latestCount = 0;
        flag = true;
    }

    private void SetHarvestedCount(int count)
    {
        latestCount = count;
        counter.CountUpAnimation($"{harvestedCountFormat}", latestCount, countDuration);
    }
    
    public void AddHarvestedCount(int count)
    {
        latestCount += count;
        counter.CountUpAnimation($"{harvestedCountFormat}", latestCount, countDuration);
    }

    public void PlayEffect()
    {
        playEffectObserve.OnNext(default);
    }
}