using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UniRx;
using UnityEngine;
using Random = UnityEngine.Random;

public class CornHarvester : MonoBehaviour
{
    private static readonly int Wait = Animator.StringToHash("Wait");
    private static readonly int PutOut = Animator.StringToHash("PutOut");
    [SerializeField] private Transform harvestedSpawnTransform;
    [SerializeField] private GameObject harvestedPrefab;
    [SerializeField] private float thrust = 100f;
    [SerializeField] private Transform machineTarget;
    // 収穫演出で出るコーンの数を制限
    [Space]
    [SerializeField] private float cullCornRate = .8f;
    [SerializeField] private int firstCornLimit = 200; 
    [SerializeField] private int secondCornLimit = 300;
    private Animator machineAnimator;
    private int runningCount;

    private readonly ReactiveProperty<int> count = new ReactiveProperty<int>(0);
    private readonly Subject<(int count, List<Collider2D> colliders)> finishHarvested = new Subject<(int count, List<Collider2D> colliders)>();
    public Subject<(int count, List<Collider2D> colliders)> FinishHarvested => finishHarvested;

    private void Start()
    {
        finishHarvested.AddTo(this);
        count.AddTo(this);
        count.BatchFrame()
            .Select(x => x.Last())
            .Pairwise()
            .Subscribe(x =>
            {
                machineAnimator?.SetTrigger(PutOut);
                runningCount++;
                StartCoroutine(Harvested(x.Current - x.Previous, (list) =>
                {
                    runningCount--;
                    if (runningCount == 0)
                    {
                        machineAnimator?.SetTrigger(Wait);
                    }
                    finishHarvested.OnNext((x.Current - x.Previous, list));
                }));
            }).AddTo(this);
    }

    public void SetMachine(Animator machinePrefab)
    {
        machineTarget.DestroyAllChildrens();
        machineAnimator = Instantiate(machinePrefab, machineTarget);
    }

    private IEnumerator Harvested(int cnt, Action<List<Collider2D>> callback = null)
    {
        var finishedList = new List<Collider2D>();
        for (int i = 0; i < cnt; i++)
        {
            VibrationManager.Instance.PlayVibrationOnce();
            var cornCount = harvestedSpawnTransform.childCount;
            if (cornCount > secondCornLimit || cornCount > firstCornLimit && Random.value <= cullCornRate)
            {
                yield return null;
                continue;
            }
            var corn = Instantiate(harvestedPrefab, harvestedSpawnTransform.position, Quaternion.identity, harvestedSpawnTransform);
            corn.GetComponent<Rigidbody2D>().AddForce(new Vector2(Random.Range(-0.3f, 0.3f), -1).normalized * thrust, ForceMode2D.Impulse);
            finishedList.Add(corn.GetComponent<Collider2D>());
            yield return null;
        }
        callback?.Invoke(finishedList);
    }

    public void AddCount(int value)
    {
        count.Value += value;
    }
}
