using System;
using UniRx;
using UnityEngine;
using UnityEngine.EventSystems;

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

public class CornSeedling : MonoBehaviour, IPointerEnterHandler
{
    [SerializeField] private CornSeedlingView seedlingView;
    private static readonly float stage0End = 0.25f;
    private static readonly float stage1End = 0.50f;
    private static readonly float stage2End = 0.75f;
    private static readonly float stage3End = 1f;

    private int period;
    private DateTime beginTime;
    private bool completed;
    
    public IObservable<Unit> Harvested => harvested; 
    private readonly Subject<Unit> harvested = new Subject<Unit>();
    private readonly ReactiveProperty<SeedlingStage> seedlingStage = new ReactiveProperty<SeedlingStage>();
    private readonly CompositeDisposable compositeDisposable = new CompositeDisposable();
    
    private void Start()
    {
        harvested.AddTo(this);
        seedlingStage.AddTo(this);
        compositeDisposable.AddTo(this);
    }

    public void PromoteGrowth(DateTime newTime)
    {
        if (completed)
        {
            return;
        }
        beginTime = newTime;
        UpdateStage();
        seedlingView.EffectGrowth();
    }

    public void SetSeedlingGene(DateTime dateTime, int periodTime, CornFieldRank rank)
    {
        completed = false;
        compositeDisposable.Clear();
        beginTime = dateTime;
        period = periodTime;
        
        // resume対応
        UpdateStage();
        var currentStage = GetCurrentStage();
        // 苗の状態復元
        seedlingView.SetView(rank, currentStage);
        if (currentStage == SeedlingStage.Stage4)
        {
            completed = true;
        }

        // 成長進捗度更新
        Observable.Interval(TimeSpan.FromSeconds(1f))
            .TakeWhile(_ => !completed)
            .Subscribe(x =>
            {
                UpdateStage();
            }).AddTo(compositeDisposable);
        
        // 更新
        seedlingStage
            .SkipLatestValueOnSubscribe()
            .TakeWhile(_ => !completed)
            .Subscribe(x =>
            {
                seedlingView.ChangeState(x);
                if (x == SeedlingStage.Stage4)
                {
                    completed = true;
                }
            }).AddTo(compositeDisposable);
    }

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

    private SeedlingStage GetCurrentStage()
    {
        var elapsed = DateTime.Now.Subtract(beginTime).TotalSeconds / period;
        if (elapsed >= stage3End)
        {
            return SeedlingStage.Stage4;
        }
        if (elapsed >= stage2End)
        {
            return SeedlingStage.Stage3;
        }
        if (elapsed >= stage1End)
        {
            return SeedlingStage.Stage2;
        }
        if (elapsed >= stage0End)
        {
            return SeedlingStage.Stage1;
        }
        return SeedlingStage.Stage0;
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        harvested.OnNext(Unit.Default);
    }
}