using System;
using System.Collections.Generic;
using System.Linq;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class BulkOrderResultData
{
    public int Number;
    public ProductRarity Rarity;
}
public class BulkOrder : MonoBehaviour
{
    public static readonly string DataTag = "BulkOrderData";
    public static readonly string MaterialNumberTag = "BulkOrderMaterialNumber";
    private static readonly string CancelCallbackTag = "BulkOrderCancelCallback";
    private static readonly string AchievedCallbackTag = "BulkOrderAchievedCallback";
    private static readonly int OpenTrigger = Animator.StringToHash("OpenTrigger");
    private static readonly int CloseTrigger = Animator.StringToHash("CloseTrigger");
    [SerializeField] private Animator backgroundAnimator;
    [SerializeField] private Button closeButton;

    [SerializeField] private Button cancelButton;
    [SerializeField] private Button deliveredButton;
    [SerializeField] private GameObject disabledButtonObject;
    [SerializeField] private Text messageText;
    [SerializeField] private Text coinText;
    [SerializeField] private Text heartText;
    [SerializeField] private BulkOrderItemView itemView1;
    [SerializeField] private BulkOrderItemView itemView2;
    [SerializeField] private BulkOrderItemView itemView3;
    [SerializeField] private BulkOrderCharacter bulkOrderCharacter;
    [SerializeField] private Image orderCharacterImage;

    private void Start()
    {
        closeButton.OnClickAsObservable().Take(1).Subscribe(_ =>
        {
            transform.parent.SetLocalScale(0);
            backgroundAnimator.SetTrigger(CloseTrigger);
            this.CallWaitForSeconds(.25f, () =>
            {
                TransitionManager.Instance.UnloadScene(GameScenes.BulkOrder);
            });
        }).AddTo(this);

        var gameData = GameDataManager.GameData;
        var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
        var messageList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderTextData>(Const.BulkOrderTextDataSheet);
        var bulkOrderData = bulkOrderList.First(data => data.id == gameData.OrderIdInProgress);
        messageText.text = messageList.First(data => data.id == gameData.OrderTextId).requestText;
        coinText.text = bulkOrderData.rewardCoin.ToString();
        heartText.text = bulkOrderData.rewardHeart.ToString();
        orderCharacterImage.sprite = bulkOrderCharacter.GetNormalIcon(gameData.OrderIconIndex);
        
        LocalCacheManager.Save(DataTag, bulkOrderData);
        cancelButton.OnClickAsObservable().ThrottleFirst(TimeSpan.FromSeconds(1f)).Subscribe(_ =>
        {
            BulkOrderCancelView.ShowDialog(() =>
            {
                // 試食数追加
                if (gameData.CompletedProductList.Exists(data => data.Number == 1))
                {
                    gameData.AddTastingCustomerCount(bulkOrderData.count1);
                }
                else if (gameData.CompletedProductList.Exists(data => data.Number == 2))
                {
                    gameData.AddTastingCustomerCount(bulkOrderData.count2);
                }
                else if (gameData.CompletedProductList.Exists(data => data.Number == 3))
                {
                    gameData.AddTastingCustomerCount(bulkOrderData.count3);
                }
                gameData.CancelOrderId = gameData.OrderIdInProgress;
                // カウントリセット
                gameData.OrderConditionCount = 0;
                GameDataManager.SaveGameData();
                LocalCacheManager.Load<Action>(CancelCallbackTag, null)?.Invoke();
                LocalCacheManager.Remove(CancelCallbackTag);
                // キャンセルと同時に閉じる
                transform.parent.SetLocalScale(0);
                backgroundAnimator.SetTrigger(CloseTrigger);
                this.CallWaitForSeconds(.25f, () =>
                {
                    TransitionManager.Instance.UnloadScene(GameScenes.BulkOrder);
                });
            });
        }).AddTo(this);

        // 納品チェック
        var orderList = new List<int>
        {
            bulkOrderData.productId1,
            bulkOrderData.productId2,
            bulkOrderData.productId3,
        };
        var completed = gameData.CompletedProductList.Count == orderList.Count(x => x != 0);
        var delivered = gameData.DeliveredOrder.Contains(bulkOrderData.id);
        if (completed)
        {
            orderCharacterImage.sprite = bulkOrderCharacter.GetThanksIcon(gameData.OrderIconIndex);
        }
        deliveredButton.interactable = completed && !delivered;
        disabledButtonObject.SetActive(!deliveredButton.interactable);
        
        // 納品
        deliveredButton.OnClickAsObservable().ThrottleFirst(TimeSpan.FromSeconds(1f)).Subscribe(_ =>
        {
            BulkOrderAchievedView.ShowDialog(() =>
            {
                // 獲得
                var rarityList = SpreadsheetDataManager.Instance.GetBaseDataList<RarityData>(Const.RarityDataSheet);
                var bonus = CalcBonus(rarityList, gameData.CompletedProductList, bulkOrderData.shopLevel);
                CoinManager.Instance.AddCoinWithEffect(bulkOrderData.rewardCoin + bonus);
                gameData.Coin = CoinManager.Instance.OwnCoin;
                gameData.Heart += bulkOrderData.rewardHeart;
                HeartMeter.Instance.AddHeart(bulkOrderData.rewardHeart);
                
                // カウントリセット
                gameData.OrderConditionCount = 0;
                gameData.DeliveredOrder.Add(bulkOrderData.id);
                gameData.BulkOrderDeliveredCount++;
                gameData.DailyBulkOrderDeliveredCount++;
#if UNITY_EDITOR
                Debug.Log($"current:{gameData.DeliveredOrder.Count} max:{bulkOrderData.maxOrder}");
#endif
                // オーダー上限を超えるとそのLevelでの注文終了
                if (gameData.DeliveredOrder.Count == bulkOrderData.maxOrder)
                {
                    gameData.DeliveredOrder.Clear();
                    gameData.AchievedOrderLevel = bulkOrderData.shopLevel;
                }
                GameDataManager.SaveGameData();
                LocalCacheManager.Load<Action>(AchievedCallbackTag, null)?.Invoke();
                LocalCacheManager.Remove(AchievedCallbackTag);
                TransitionManager.Instance.UnloadScene(GameScenes.BulkOrder);
            });
            transform.SetLocalScale(0);
            backgroundAnimator.SetTrigger(CloseTrigger);
        }).AddTo(this);
        
        var productList = SpreadsheetDataManager.Instance.GetBaseDataList<ProductData>(Const.ProductDataSheet);
        if (productList.FirstOrDefault(data => data.id == bulkOrderData.productId1) is ProductData data1)
        {
            var countByVolume = bulkOrderData.count1 / data1.volume;
            var productData = new ProductData(data1, countByVolume);
            productData.volume *= countByVolume;
            itemView1.SetData(productData);
            if (gameData.CompletedProductList.FirstOrDefault(data => data.Number == 1) is BulkOrderResultData resultData)
            {
                itemView1.SetCooked(resultData.Rarity);
            }
            else
            {
                itemView1.SetButtonActive(itemView1.CheckAmount(productData));
            }
            itemView1.CookingButton.ThrottleFirst(TimeSpan.FromSeconds(1f)).Subscribe(_ =>
            {
                LocalCacheManager.Save(Const.ProductViewTypeTag, ProductViewType.BulkOrder);
                LocalCacheManager.Save(MaterialNumberTag, 1);
                LocalCacheManager.Save(PopcornGameManager.CookingDataTag, productData);
                RecipeDetailView.ShowDialog();
            }).AddTo(itemView1);
            itemView1.gameObject.SetActive(true);
        }
        else
        {
            itemView1.gameObject.SetActive(false);
        }
        if (productList.FirstOrDefault(data => data.id == bulkOrderData.productId2) is ProductData data2)
        {
            var countByVolume = bulkOrderData.count2 / data2.volume;
            var productData = new ProductData(data2, countByVolume);
            productData.volume *= countByVolume;
            itemView2.SetData(productData);
            if (gameData.CompletedProductList.FirstOrDefault(data => data.Number == 2) is BulkOrderResultData resultData)
            {
                itemView2.SetCooked(resultData.Rarity);
            }
            else
            {
                itemView2.SetButtonActive(itemView2.CheckAmount(productData));
            }
            itemView2.CookingButton.ThrottleFirst(TimeSpan.FromSeconds(1f)).Subscribe(_ =>
            {
                LocalCacheManager.Save(Const.ProductViewTypeTag, ProductViewType.BulkOrder);
                LocalCacheManager.Save(MaterialNumberTag, 2);
                LocalCacheManager.Save(PopcornGameManager.CookingDataTag, productData);
                RecipeDetailView.ShowDialog();
            }).AddTo(itemView2);
            itemView2.gameObject.SetActive(true);
        }
        else
        {
            itemView2.gameObject.SetActive(false);
        }
        if (productList.FirstOrDefault(data => data.id == bulkOrderData.productId3) is ProductData data3)
        {
            var countByVolume = bulkOrderData.count3 / data3.volume;
            var productData = new ProductData(data3, countByVolume);
            productData.volume *= countByVolume;
            itemView3.SetData(productData);
            if (gameData.CompletedProductList.FirstOrDefault(data => data.Number == 3) is BulkOrderResultData resultData)
            {
                itemView3.SetCooked(resultData.Rarity);
            }
            else
            {
                itemView3.SetButtonActive(itemView3.CheckAmount(productData));
            }
            itemView3.CookingButton.ThrottleFirst(TimeSpan.FromSeconds(1f)).Subscribe(_ =>
            {
                LocalCacheManager.Save(MaterialNumberTag, 3);
                LocalCacheManager.Save(PopcornGameManager.CookingDataTag, productData);
                RecipeSelectDialog.ShowDialog(ProductViewType.BulkOrder);
            }).AddTo(itemView3);
            itemView3.gameObject.SetActive(true);
        }
        else
        {
            itemView3.gameObject.SetActive(false);
        }
    }

    public static void ShowDialog(Action onComplete = null, Action onAchieved = null, Action onCancel = null)
    {
        LocalCacheManager.Remove(Const.ProductViewTypeTag);
        LocalCacheManager.Save(AchievedCallbackTag, onAchieved);
        LocalCacheManager.Save(CancelCallbackTag, onCancel);
        TransitionManager.Instance.LoadSceneAdditive(GameScenes.BulkOrder);
    }

    public static int CalcBonus(List<RarityData> rarityList, List<BulkOrderResultData> resultData, int shopLevel)
    {
        var totalBonus = 0;
        var hasRarityList = resultData.Where(data => data.Rarity != ProductRarity.Normal).ToList();
        if (hasRarityList.Count == 0)
        {
            return 0;
        }
        foreach (var progressData in hasRarityList)
        {
            var bonusRate = rarityList.FirstOrDefault(data => data.Rarity == progressData.Rarity)?.bulkOrderBonus ?? 0;
            totalBonus += bonusRate * shopLevel;
        }
        return Mathf.CeilToInt((float) totalBonus / hasRarityList.Count);
    }
}