using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;

public enum CornFieldRank
{
    Rank1,
    Rank2,
    Rank3
}

public class CornField : MonoBehaviour
{
    [SerializeField] private Button promoteGrowthButton;
    [SerializeField] private GameObject harvestPrefab;
    [SerializeField] private Transform harvestInsertPosition;
    [SerializeField] private CornHarvester cornHarvester;
    [Space]
    [SerializeField] private List<PlantLine> plantLines = new List<PlantLine>();
    private readonly List<PlantLine> availableLines = new List<PlantLine>();
    private static readonly int maxPeriod = 60;
    private static readonly int minPeriod = 45;
    
    private readonly ReactiveProperty<int> harvestedCornCount = new ReactiveProperty<int>();
    private readonly CompositeDisposable compositeDisposable = new CompositeDisposable();
    // Start is called before the first frame update
    void Start()
    {
        compositeDisposable.AddTo(this);
        this.UpdateAsObservable()
            .Where(_ => Input.GetKeyDown(KeyCode.R))
            .Take(1)
            .Subscribe(_ => TransitionManager.Instance.LoadScene(GameScenes.CornField)).AddTo(this);
        
        // データ
        // 解放済みの畑, 畑の質, 収穫機レベル
        var plantSetting = new List<PlantLineType>()
        {
            PlantLineType.Center,
            PlantLineType.Bottom,
        };
        var fieldLevel = (int)CornFieldRank.Rank3;
        var machineLevel = 1;
        // コーン株の進行度
        var progressDataList = new List<SeedlingProgressData>()
        {
            GenerateSeedlingData(PlantLineType.Center),
        };

        // 畑リセット
        availableLines.Clear();
        foreach (var line in plantLines)
        {
            line.gameObject.SetActive(false);
        }
        
        // セーブデータから畑を復元
        foreach (var line in plantSetting)
        {
            Debug.Log($"{line}");
            var plantLine = plantLines.First(x => x.LineName == line);
            plantLine.gameObject.SetActive(true);
            availableLines.Add(plantLine);
            // 初回データ作成
            if (!progressDataList.Exists(x => x.type == line))
            {
                progressDataList.Add(GenerateSeedlingData(line));
            }
        }

        // 株設定
        foreach (var line in availableLines)
        {
            var lineData = progressDataList.First(x => x.type == line.LineName);
            var i = 0;
            foreach (var seedling in line.Seedlings)
            {
                var index = i;
                i++;
                seedling.SetSeedlingGene(lineData.Seedlings[index].firstTime, lineData.Seedlings[index].period, (CornFieldRank)fieldLevel);
                seedling.Harvested.Subscribe(_ =>
                {
                    // 収穫
                    VibrationManager.Instance.PlayVibrationOnce();
                    for (int j = 0; j < GetHarvestCount((CornFieldRank)fieldLevel); j++)
                    {
                        var harvestedCorn = 20;
                        harvestedCornCount.Value += harvestedCorn;
                        var harvestAnimation = Instantiate(harvestPrefab, seedling.transform);
                        this.CallWaitForSeconds(.5f, () =>
                        {
                            var beginPos = harvestAnimation.transform.position;
                            this.CallLerp(.4f, f =>
                            {
                                harvestAnimation.transform.position = Vector3.Lerp(beginPos, harvestInsertPosition.position, f.EaseInQuadratic());
                            }, () =>
                            {
                                cornHarvester.AddCount(harvestedCorn);
                                Destroy(harvestAnimation);
                            });
                        });
                    }
                    // 新しい苗
                    lineData.Seedlings[index] = GenerateSeedlingGene();
                    seedling.SetSeedlingGene(lineData.Seedlings[index].firstTime, lineData.Seedlings[index].period, CornFieldRank.Rank1);
                }).AddTo(compositeDisposable);
            }
        }

        // 時短ボタン
        promoteGrowthButton.OnClickAsObservable().Subscribe(_ =>
        {
            VibrationManager.Instance.PlayVibrationOnce();
            foreach (var line in availableLines)
            {
                var lineData = progressDataList.First(x => x.type == line.LineName);
                var i = 0;
                foreach (var seedling in line.Seedlings)
                {
                    if (Random.Range(0, 2) == 0)
                    {
                        var tmpData = lineData.Seedlings[i];
                        tmpData.firstTime = lineData.Seedlings[i].firstTime.AddSeconds(-1);
                        lineData.Seedlings[i] = tmpData;
                        seedling.PromoteGrowth(lineData.Seedlings[i].firstTime);
                    }
                }
            }
            // 設定のセーブ
        }).AddTo(compositeDisposable);
    }

    private SeedlingProgressData GenerateSeedlingData(PlantLineType type)
    {
        switch (type)
        {
            case PlantLineType.Top:
                return new SeedlingProgressData
                {
                    type = PlantLineType.Top,
                    Seedlings = new List<(DateTime firstTime, int period)>()
                    {
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                    }
                };
            case PlantLineType.Center:
                return new SeedlingProgressData
                {
                    type = PlantLineType.Center,
                    Seedlings = new List<(DateTime firstTime, int period)>()
                    {
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                    }
                };
                break;
            case PlantLineType.Bottom:
                return new SeedlingProgressData
                {
                    type = PlantLineType.Bottom,
                    Seedlings = new List<(DateTime firstTime, int period)>()
                    {
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                        GenerateSeedlingGene(),
                    }
                };
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, null);
        }
    }

    private (DateTime, int) GenerateSeedlingGene()
    {
        // return (DateTime.Now, Random.Range(minPeriod, maxPeriod + 1));
        return (DateTime.Now.AddSeconds(-Random.Range(0, 15)), 15 + Random.Range(0, 15));
    }

    private int GetHarvestCount(CornFieldRank rank)
    {
        switch (rank)
        {
            case CornFieldRank.Rank1:
                return 1;
            case CornFieldRank.Rank2:
                return 2;
            case CornFieldRank.Rank3:
                return 3;
            default:
                throw new ArgumentOutOfRangeException(nameof(rank), rank, null);
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
