using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using MyGame.Scripts;
using UniRx;
using UniRx.Triggers;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;

public class KitchenManager : MonoBehaviour
{
    private static readonly double refreshWaitTime = 300;
    [SerializeField] int refreshRewardCoin = 100;
    [SerializeField] private Button cookingButton;
    [SerializeField] private Button adButton;
    [SerializeField] private KitchenView kitchenView;
    [SerializeField] private BulkOrderIndicatorView orderIndicatorView;
    
    // Start is called before the first frame update
    void Start()
    {
        SoundManager.Instance.PlayBGM("bgm_Main");
        var gameData = GameDataManager.GameData;
        
        // レシピの表示
        cookingButton.OnClickAsObservable().Subscribe(_ =>
        {
            RecipeSelectDialog.ShowDialog(ProductViewType.Default, () =>
            {
                if (gameData.isFirstPlay && TutorialManager.Instance.Index == 2)
                {
                    var go = FindObjectOfType<FooterManager>().transform;
                    go.transform.FindChildByName("Button_field", t =>
                    {
                        TutorialManager.Instance.ShowTutorialMask(go.parent, t as RectTransform, true);
                    });
                }
            });
        });
        
        // tutorial
#if UNITY_EDITOR
        Debug.Log($"isFirstPlay:{gameData.isFirstPlay}");
#endif
        if (gameData.isFirstPlay)
        {
            if (TutorialManager.Instance.Index == 1)
            {
                gameData.CornSeed = 90;
                gameData.Coin = 10;
                // 店舗レベル1達成表示
                LocalCacheManager.Save(ShopLevelUp.DataTag, 1);
                LocalCacheManager.Save(ShopLevelUp.CallbackTag, new Action(() =>
                {
                    TutorialManager.Instance.ShowTutorialConversation(1, () =>
                    {
                        // マスク表示
                        var buttonRectTransform = cookingButton.transform as RectTransform;
                        var go = TutorialManager.Instance.ShowTutorialMask(buttonRectTransform.parent, buttonRectTransform);
                        cookingButton.OnClickAsObservable().Take(1).Subscribe(_ =>
                        {
                            DestroyImmediate(go);
                        }).AddTo(this);
                    });
                }));
                TransitionManager.Instance.LoadSceneAdditive(GameScenes.StoreLevel);
            }
            else if (TutorialManager.Instance.Index == 6)
            {
                gameData.CornSeed = 150;
                gameData.Material.First(m => m.Id == 2).Amount = 1;
                TutorialManager.Instance.ShowTutorialConversation(7, () =>
                {
                    // マスク表示
                    var buttonRectTransform = cookingButton.transform as RectTransform;
                    var go = TutorialManager.Instance.ShowTutorialMask(buttonRectTransform.parent, buttonRectTransform);
                    cookingButton.OnClickAsObservable().Take(1).Subscribe(_ =>
                    {
                        DestroyImmediate(go);
                    }).AddTo(this);
                });
            }
            else if (TutorialManager.Instance.Index > 7)
            {
                TutorialManager.Instance.ShowTutorialConversation(10, () =>
                {
                    var go = FindObjectOfType<FooterManager>().transform;
                    go.transform.FindChildByName("Button_shop", t =>
                    {
                        TutorialManager.Instance.ShowTutorialMask(go.parent, t as RectTransform, true);
                    });
                });
            }
        }
        
        CoinManager.Instance.ChangeCoin(gameData.Coin);
        HeartMeter.Instance.Initialize(gameData.ViewedShopLevel, gameData.Heart);
        GameDataObserver.Instance.ShopLevelUpdate
            .Where(x => x)
            .Subscribe(x =>
            {
                LocalCacheManager.Save(ShopLevelUp.DataTag, gameData.ViewedShopLevel + 1);
                TransitionManager.Instance.LoadSceneAdditive(GameScenes.StoreLevel);
            }).AddTo(this);

        kitchenView.Initialize();
        adButton.OnClickAsObservable().ThrottleFirst(TimeSpan.FromSeconds(.3f)).Subscribe(_ =>
        {
            // 動画視聴POP
            GetRewardDialog.ShowCoinDialog(() =>
            {
                CoinGetDialog.ShowDialog(refreshRewardCoin, () =>
                {
                    adButton.gameObject.SetActive(false);
                    kitchenView.SetNormalAnimation();
                    
                    CoinManager.Instance.AddCoinWithEffect(refreshRewardCoin);
                    gameData.Coin = CoinManager.Instance.OwnCoin;
                    gameData.kitchenRefreshTime = DateTime.UtcNow.AddSeconds(refreshWaitTime).ToBinary();
                    GameDataManager.SaveGameData();
                });
            });
        }).AddTo(this);
        
        // 休憩リワード
        var remaining = (int) DateTime.FromBinary(gameData.kitchenRefreshTime).Subtract(DateTime.UtcNow).TotalSeconds;
        if (remaining > 0 || gameData.isFirstPlay)
        {
            adButton.gameObject.SetActive(false);
            kitchenView.SetNormalAnimation();
        }
        else
        {
            adButton.gameObject.SetActive(true);
            kitchenView.SetTiredAnimation();
        }
#if UNITY_EDITOR
        Debug.Log($"remaining: {remaining}");
#endif

        // 大量注文
        var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
        var result = CheckBulkOrder();
        var bulkOrderData = bulkOrderList.FirstOrDefault(data => data.id == gameData.OrderIdInProgress);
        var achieved = bulkOrderData is null || gameData.DeliveredOrder.Contains(bulkOrderData.id) || gameData.AchievedOrderLevel == bulkOrderData.shopLevel;
        var cancelled = gameData.OrderIdInProgress == gameData.CancelOrderId;
        GameDataManager.SaveGameData();

        if (bulkOrderData != null)
        {
            var orderList = new List<int>
            {
                bulkOrderData.productId1,
                bulkOrderData.productId2,
                bulkOrderData.productId3,
            };
            var completed = gameData.CompletedProductList.Count == orderList.Count(x => x != 0);
            orderIndicatorView.SetBadgeActive(completed && !achieved);
        }
        else
        {
            orderIndicatorView.SetBadgeActive(false);
        }
        
        orderIndicatorView.SetIndicate(result.result, achieved || cancelled);
        if (result.result)
        {
            SoundManager.Instance.StopSE("se_Main_phone_sound");
            
            var messageList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderTextData>(Const.BulkOrderTextDataSheet);
            var nextMessageList = messageList.Where(data => data.shopLevel == result.nextOrderLevel).ToList();
            orderIndicatorView.TappedPhone.ThrottleFirst(TimeSpan.FromSeconds(1f)).Take(1).Subscribe(_ =>
            {
                // タップで更新
                gameData.CompletedProductList.Clear();
                gameData.OrderIdInProgress = result.nextOrderId;
                if (nextMessageList.Exists(data => data.id == gameData.OrderTextId))
                {
                    var nextMessageIndex = nextMessageList.FindIndex(data => data.id == gameData.OrderTextId) + 1;
                    gameData.OrderTextId = nextMessageList[nextMessageIndex >= nextMessageList.Count ? 0 : nextMessageIndex].id;
                }
                else
                {
                    gameData.OrderTextId = nextMessageList.First().id;
                }
                GameDataManager.SaveGameData();
                
                var orderData = bulkOrderList.First(data => data.id == result.nextOrderId);
                LocalCacheManager.Save(BulkOrder.DataTag, orderData);
                TransitionManager.Instance.LoadSceneAdditive(GameScenes.BulkOrderTelephone);
                
                // 通知をタップ後タップ動作を切り替える
                orderIndicatorView.SetIndicate(false, false);
                orderIndicatorView.TappedPhone
                    .ThrottleFirst(TimeSpan.FromSeconds(1f))
                    .Take(1)
                    .Subscribe(__ =>
                    {
                        BulkOrder.ShowDialog(
                            onAchieved: () =>
                            {
                                orderIndicatorView.SetIndicate(false, true);
                                orderIndicatorView.SetBadgeActive(false);
                            },
                            onCancel: () =>
                            {
                                orderIndicatorView.SetIndicate(false, true);
                                orderIndicatorView.SetBadgeActive(false);
                            });
                    }).AddTo(this);
            }).AddTo(this);
        }
        else
        {
            if (gameData.OrderIdInProgress != gameData.CancelOrderId)
            {
                orderIndicatorView.TappedPhone
                    .ThrottleFirst(TimeSpan.FromSeconds(1f))
                    .Subscribe(_ =>
                    {
                        BulkOrder.ShowDialog(
                            onAchieved: () =>
                            {
                                orderIndicatorView.SetIndicate(false, true);
                                orderIndicatorView.SetBadgeActive(false);
                            },
                            onCancel: () =>
                            {
                                orderIndicatorView.SetIndicate(false, true);
                                orderIndicatorView.SetBadgeActive(false);
                            });
                    }).AddTo(this);
            }
        }

#if UNITY_EDITOR
        Market.StockFlavorLog();
#endif
    }

    private (bool result, int nextOrderId, int nextOrderLevel) CheckBulkOrder()
    {
        var gameData = GameDataManager.GameData;
        var nextOrderLevel = 0;
        var nextOrderId = gameData.OrderIdInProgress;
        var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
        if (!(bulkOrderList.FirstOrDefault(data => data.shopLevel >= gameData.AchievedOrderLevel + 1) is BulkOrderData bulkOrderData))
        {
            return (false, nextOrderId, nextOrderLevel);
        }
        
        nextOrderLevel = bulkOrderData.shopLevel;
        if (gameData.ViewedShopLevel < nextOrderLevel)
        {
            return (false, nextOrderId, nextOrderLevel);
        }
        
        var achieved = gameData.DeliveredOrder.Contains(gameData.OrderIdInProgress);
        var nextOrderList = bulkOrderList.Where(data => data.shopLevel == nextOrderLevel).ToList();
        if (!nextOrderList.Exists(data => data.id == gameData.OrderIdInProgress))
        {
            // まだ次のオーダーが設定されてない場合nextOrderListの一番若いIDを設定
            nextOrderId = nextOrderList.First().id;
        }
        else if (achieved || gameData.OrderIdInProgress == gameData.CancelOrderId && gameData.CancelOrderId > 0)
        {
            // 達成済みか、キャンセルされた場合次のIDを設定
            var orderList = nextOrderList.Where(data => !gameData.DeliveredOrder.Contains(data.id)).ToList();
            var nextIndex = orderList.FindIndex(data => data.id > gameData.OrderIdInProgress);
            nextOrderId = orderList[Mathf.Max(0, nextIndex)].id;
        }

        if (gameData.OrderIdInProgress == nextOrderId)
        {
            return (false, nextOrderId, nextOrderLevel);
        }

        var orderData = nextOrderList.First(data => data.id == nextOrderId);
        var isFirst = !nextOrderList.Exists(data => data.id == gameData.CancelOrderId);
        var condition = isFirst ? orderData.firstOrderCondition : orderData.retryCondition;

        // 条件チェック
        return (condition <= gameData.OrderConditionCount, nextOrderId, nextOrderLevel);
    }

    private void OnDestroy()
    {
        if (SoundManager.ExistsInstance)
        {
            SoundManager.Instance.StopSE("se_Main_phone_sound");
        }
    }
}
