using System;
using System.Linq;
using MyGame.Scripts;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class RecipeDetailView : MonoBehaviour
{
    private static readonly string CallbackTag = "RecipeDetailViewCallback";
    private static readonly int OpenTrigger = Animator.StringToHash("OpenTrigger");
    private static readonly int CloseTrigger = Animator.StringToHash("CloseTrigger");
    private static readonly string flavorStockFormat = "所持数 :{0}";
    private static readonly string cornAmountFormat = "{0}/{1}";
    private static readonly string flavorAmountFormat = "{0} / {1}";

    [SerializeField] private Animator backgroundAnimator;
    [SerializeField] private Button cancelButton;
    [SerializeField] private Button nextButton;
    [SerializeField] private GameObject disabledNextButton;
    [SerializeField] private GameObject tankCaution;
    [SerializeField] private PanSelector panSelector;
    [SerializeField] private Text flavorName;
    [SerializeField] private Text flavorPrice;
    [SerializeField] private Text flavorVolume;
    [SerializeField] private GameObject flavorVolumeObject;
    [SerializeField] private Text flavorStock;
    [SerializeField] private Text flavorText;
    [SerializeField] private Transform flavorImageTarget;
    [SerializeField] private Text cornAmountText;
    [SerializeField] private Text flavor1AmountText;
    [SerializeField] private Text flavor2AmountText;
    [SerializeField] private Transform flavor1IconTarget;
    [SerializeField] private Transform flavor2IconTarget;
    [SerializeField] private GameObject flavor2View;
    
    private Color redColor;

    private void Start()
    {
        ColorUtility.TryParseHtmlString(Const.RedColorString, out redColor);
        var viewType = LocalCacheManager.Load(Const.ProductViewTypeTag, ProductViewType.Default);
        var data = LocalCacheManager.Load<ProductData>(PopcornGameManager.CookingDataTag);
        var gameData = GameDataManager.GameData;

        if (gameData.isFirstPlay)
        {
            if (TutorialManager.Instance.Index == 1)
            {
                TutorialManager.Instance.ShowTutorialConversation(2, () =>
                {
                    LocalCacheManager.Load<Action>(CallbackTag, null)?.Invoke();
                    TransitionManager.Instance.UnloadScene(GameScenes.RecipeChoice);
                    TransitionManager.Instance.UnloadScene(GameScenes.Recipe);
                });
            }
            else if (TutorialManager.Instance.Index == 7)
            {
                // マスク表示
                var go = TutorialManager.Instance.ShowTutorialMask(transform.parent.parent, nextButton.transform as RectTransform);
                nextButton.OnClickAsObservable().Take(1).Subscribe(_ =>
                {
                    DestroyImmediate(go);
                }).AddTo(this);
            }
        }
        
        cancelButton.OnClickAsObservable().Take(1).Subscribe(_ =>
        {
            transform.parent.SetLocalScale(0);
            backgroundAnimator.SetTrigger(CloseTrigger);
            this.CallWaitForSeconds(.25f, () =>
            {
                LocalCacheManager.Load<Action>(CallbackTag, null)?.Invoke();
                TransitionManager.Instance.UnloadScene(GameScenes.RecipeChoice);
            });
        }).AddTo(this);
        
        nextButton.OnClickAsObservable().Take(1).Subscribe(_ =>
        {
            LocalCacheManager.Save(PopcornGameManager.PanDataTag, panSelector.SelectedPanData.Value);
            // 消費
            gameData.CornSeed -= data.MaterialList[0].amount;
            if (gameData.Material.FirstOrDefault(x => x.Id == data.MaterialList[1].id) is MaterialData material1)
            {
                material1.Amount -= data.MaterialList[1].amount;
            }
            if (data.GetMaterialCount() == 3 && gameData.Material.FirstOrDefault(x => x.Id == data.MaterialList[2].id) is MaterialData material2)
            {
                material2.Amount -= data.MaterialList[2].amount;
            }
            GameDataManager.SaveGameData();
            TransitionManager.Instance.LoadScene(GameScenes.Cooking);
        }).AddTo(this);

        SetRecipe(data, viewType);
        var isPassedAmount = CheckAmount(data);
        var isPassedTank = CheckTank(data);

        switch (viewType)
        {
            case ProductViewType.Default:
                nextButton.interactable = isPassedAmount && isPassedTank;
                panSelector.gameObject.SetActive(!isPassedAmount || isPassedTank);
                disabledNextButton.SetActive(!isPassedAmount || !isPassedTank);
                tankCaution.SetActive(isPassedAmount && !isPassedTank);
                break;
            case ProductViewType.BulkOrder:
                nextButton.interactable = isPassedAmount;
                panSelector.gameObject.SetActive(true);
                disabledNextButton.SetActive(!nextButton.interactable);
                tankCaution.SetActive(false);
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    public void SetRecipe(ProductData data, ProductViewType viewType)
    {
        var gameData = GameDataManager.GameData;
        
        // 在庫
        var shopStock = gameData.ShopStock.Count(stockData => stockData.FlavorId == data.id);
        var tankStock = gameData.StorageTanks.FindAll(x => x.FlavorId == data.id).Sum(x => x.Stock);
        flavorStock.text = string.Format(flavorStockFormat, shopStock + tankStock);
        flavorName.text = data.name;
        flavorPrice.text = data.price.ToString();
        flavorVolume.text = data.volume.ToString();
        flavorText.text = data.text;
        flavorImageTarget.DestroyAllChildrens();
        Instantiate(data.GetIconPrefab(), flavorImageTarget);
        cornAmountText.text = string.Format(cornAmountFormat, gameData.CornSeed, data.MaterialList[0].amount);
        
        switch (viewType)
        {
            case ProductViewType.Default:
                flavorVolumeObject.SetActive(true);
                flavorPrice.transform.parent.gameObject.SetActive(true);
                flavorVolume.transform.parent.gameObject.SetActive(false);
                break;
            case ProductViewType.BulkOrder:
                flavorVolumeObject.SetActive(false);
                flavorPrice.transform.parent.gameObject.SetActive(false);
                flavorStock.transform.parent.gameObject.SetActive(false);
                flavorVolume.transform.parent.gameObject.SetActive(true);
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(viewType), viewType, null);
        }

        var shopData = SpreadsheetDataManager.Instance.GetBaseDataList<ShopData>(Const.ShopDataSheet);
        var flavor1Amount = gameData.Material.FirstOrDefault(x => x.Id == data.MaterialList[1].id)?.Amount ?? 0;
        flavor1AmountText.text = string.Format(flavorAmountFormat, flavor1Amount, data.MaterialList[1].amount);
        if (shopData.FirstOrDefault(sData => sData.itemId == data.MaterialList[1].id)?.GetIconPrefab() is Transform prefab1)
        {
            flavor1IconTarget.DestroyAllChildrens();
            Instantiate(prefab1, flavor1IconTarget);
        }
        var flavor2Amount = gameData.Material.FirstOrDefault(x => x.Id == data.MaterialList[2].id)?.Amount ?? 0;
        flavor2AmountText.text = string.Format(flavorAmountFormat, flavor2Amount, data.MaterialList[2].amount);
        if (shopData.FirstOrDefault(sData => sData.itemId == data.MaterialList[2].id)?.GetIconPrefab() is Transform prefab2)
        {
            flavor2IconTarget.DestroyAllChildrens();
            Instantiate(prefab2, flavor2IconTarget);
        }
        flavor2View.SetActive(data.GetMaterialCount() == 3);
    }

    private bool CheckAmount(ProductData productData)
    {
        var flag = true;
        var gameData = GameDataManager.GameData;
        if (gameData.CornSeed < productData.MaterialList[0].amount)
        {
            flag = false;
            cornAmountText.color = redColor;
        }
        if ((gameData.Material.FirstOrDefault(data => data.Id == productData.MaterialList[1].id)?.Amount ?? 0) < productData.MaterialList[1].amount)
        {
            flag = false;
            flavor1AmountText.color = redColor;
        }
        if (productData.GetMaterialCount() == 3 && (gameData.Material.FirstOrDefault(data => data.Id == productData.MaterialList[2].id)?.Amount ?? 0) < productData.MaterialList[2].amount)
        {
            flag = false;
            flavor2AmountText.color = redColor;
        }
        return flag;
    }

    private bool CheckTank(ProductData data)
    {
        var gameData = GameDataManager.GameData;
        // 店頭の空き確認
        if (data.volume <= Market.ShopStockCount - gameData.ShopStock.Count)
        {
            return true;
        }

        // 空のタンク、同じフレーバーのタンク空き確認
        return gameData.StorageTanks
            .Where(tank => tank.IsEmpty || tank.FlavorId == data.id && !tank.IsFull)
            .Any(tank => data.volume <= tank.Capacity - tank.Stock);
    }
    
    public static void ShowDialog(Action onClose = null)
    {
        LocalCacheManager.Save(CallbackTag, onClose);
        TransitionManager.Instance.LoadSceneAdditive(GameScenes.RecipeChoice);
    }
}