using System;
using UniRx;
using UnityEngine;
using Random = UnityEngine.Random;

public enum SeedlingStage
{
    Stage1,
    Stage2,
    Stage3,
    Stage4
}

public enum SeedlingRank
{
    Rank1,
    Rank2,
    Rank3
}

public class CornSeedling : MonoBehaviour
{
    [SerializeField] private GameObject seedlingStage1;
    [SerializeField] private GameObject seedlingStage2;
    [SerializeField] private GameObject seedlingStage3;
    [SerializeField] private GameObject seedlingStage4;
    [SerializeField] private Animator growingArrow;
    private readonly int growingTriggerHash = Animator.StringToHash("GrowingTrigger");
    private readonly int nextStageTriggerHash = Animator.StringToHash("NextStageTrigger");
    private static readonly float stage1End = 0.32f;
    private static readonly float stage2End = 0.67f;
    private static readonly float stage3End = 1f;

    private int period;
    private DateTime beginTime;
    private SeedlingRank seedlingRank; // 苗の良さ(1~3
    private bool completed;
    
    private readonly ReactiveProperty<SeedlingStage> seedlingStage = new ReactiveProperty<SeedlingStage>();
    private readonly CompositeDisposable compositeDisposable = new CompositeDisposable();
    
    private void Start()
    {
        seedlingStage.AddTo(this);
        compositeDisposable.AddTo(this);
    }

    private void ResetGrowth()
    {
        seedlingStage1.SetActive(false);
        seedlingStage2.SetActive(false);
        seedlingStage3.SetActive(false);
        seedlingStage4.SetActive(false);
    }

    public void PromoteGrowth(int newPeriod)
    {
        growingArrow.SetTrigger(growingTriggerHash);
        period = newPeriod;
        UpdateStage();
    }

    public void SetSeedlingGene(DateTime dateTime, int periodTime, SeedlingRank rank)
    {
        completed = false;
        compositeDisposable.Clear();
        ResetGrowth();
        beginTime = dateTime;
        period = periodTime;
        seedlingRank = rank;
        
        // resume対応
        // 途中からの場合アニメーションを勧めておく処理
        var stage = GetCurrentStage();
        seedlingStage.SetValueAndForceNotify(stage);
        switch (stage)
        {
            case SeedlingStage.Stage1:
                seedlingStage1.SetActive(true);
                break;
            case SeedlingStage.Stage2:
                seedlingStage2.SetActive(true);
                break;
            case SeedlingStage.Stage3:
                seedlingStage3.SetActive(true);
                break;
            case SeedlingStage.Stage4:
                seedlingStage4.SetActive(true);
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
        
        // 成長ロジック
        seedlingStage
            .TakeWhile(_ => !completed)
            .Subscribe(x =>
            {
                switch (x)
                {
                    case SeedlingStage.Stage1:
                        break;
                    case SeedlingStage.Stage2:
                        seedlingStage1.GetComponent<Animator>().SetTrigger(nextStageTriggerHash);
                        this.CallWaitForSeconds(.25f, () =>
                        {
                            seedlingStage2.SetActive(true);
                        });
                        break;
                    case SeedlingStage.Stage3:
                        seedlingStage2.GetComponent<Animator>().SetTrigger(nextStageTriggerHash);
                        this.CallWaitForSeconds(.25f, () =>
                        {
                            seedlingStage3.SetActive(true);
                        });
                        break;
                    case SeedlingStage.Stage4:
                        seedlingStage3.GetComponent<Animator>().SetTrigger(nextStageTriggerHash);
                        this.CallWaitForSeconds(.25f, () =>
                        {
                            completed = true;
                            seedlingStage4.SetActive(true);
                        });
                        break;
                    default:
                        throw new ArgumentOutOfRangeException(nameof(x), x, null);
                }
            }).AddTo(compositeDisposable);

        // 成長進捗度
        Observable.Interval(TimeSpan.FromSeconds(1f))
            .TakeWhile(_ => !completed)
            .Subscribe(x =>
            {
                UpdateStage();
            }).AddTo(compositeDisposable);
    }

    private void UpdateStage()
    {
        seedlingStage.Value = GetCurrentStage();
    }

    private SeedlingStage GetCurrentStage()
    {
        var elapsed = DateTime.Now.Subtract(beginTime).TotalSeconds / period;
        Debug.Log($"{elapsed:F2}");
        if (elapsed >= stage3End)
        {
            return SeedlingStage.Stage4;
        }
        if (elapsed >= stage2End)
        {
            return SeedlingStage.Stage3;
        }
        if (elapsed >= stage1End)
        {
            return SeedlingStage.Stage2;
        }
        return SeedlingStage.Stage1;
    }
}