using System;
using System.Linq;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class CookingResult : MonoBehaviour
{
    private static readonly string RarityTextFormat = "売値 ＋{0}% UP";
    private static readonly string QuantityTextFormat = "x{0}";
    [SerializeField] private GameObject smokeEffect;
    [SerializeField] private GameObject glitterEffect;
    [SerializeField] private Button centerOkButton;
    [SerializeField] private Button perfectButton;
    [SerializeField] private Button leftOkButton;
    [SerializeField] private Button destructionButton;
    [SerializeField] private Image popcornImage;
    [SerializeField] private Text popcornText;
    [SerializeField] private Text popcornTextPerfect;
    [SerializeField] private TextMeshProUGUI quantityText;
    [SerializeField] private Text rarityText;
    [SerializeField] private RarityView rarityView;
    [SerializeField] private GameObject detailObject;
    [SerializeField] private GameObject explainObject;
    [SerializeField] private GameObject explainWithRarityObject;
    [SerializeField] private GameObject perfectResultObject;
    [SerializeField] private GameObject goodResultObject;
    [SerializeField] private GameObject failureResultObject;

    private void Start()
    {
        var (productData, rarityData, resultData, successAction) = LocalCacheManager.Load<(ProductData, RarityData, CornResult, Action)>(PopcornGameManager.CookingResultDataTag);
        var result = new ReactiveProperty<CornResult>(resultData).AddTo(this);
        SetData(productData, rarityData);
        result.Subscribe(r =>
        {
            SetUI(r);
            if (r != CornResult.Failure)
            {
                successAction?.Invoke();
            }
        }).AddTo(this);

        // 各種ボタン押下後、獲得処理
        centerOkButton.OnClickAsObservable().Subscribe(_ =>
        {
            // 獲得、遷移
            AddStock(productData, rarityData.Rarity);
            TransitionManager.Instance.LoadScene(GameScenes.Main);
        }).AddTo(this);
        leftOkButton.OnClickAsObservable().Subscribe(_ =>
        {
            // 獲得、遷移
            AddStock(productData);
            TransitionManager.Instance.LoadScene(GameScenes.Main);
        }).AddTo(this);
        perfectButton.OnClickAsObservable().Subscribe(_ =>
        {
            // 広告視聴後、結果上書き
            result.Value = CornResult.Perfect;
        }).AddTo(this);
        destructionButton.OnClickAsObservable().Subscribe(_ =>
        {
            // 遷移
            TransitionManager.Instance.LoadScene(GameScenes.Main);
        }).AddTo(this);
    }

    private void SetData(ProductData recipe, RarityData rarity)
    {
        // popcornImage
        popcornText.text = recipe.name;
        popcornTextPerfect.text = recipe.name;
        quantityText.text = string.Format(QuantityTextFormat, recipe.volume);
        rarityText.text = string.Format(RarityTextFormat, rarity.rate - 100);
        rarityView.SetRarity(rarity.Rarity);
    }

    private void SetUI(CornResult result)
    {
        centerOkButton.gameObject.SetActive(false);
        perfectButton.gameObject.SetActive(false);
        leftOkButton.gameObject.SetActive(false);
        destructionButton.gameObject.SetActive(false);

        this.CallWaitForSeconds(1.25f, () =>
        {
            centerOkButton.gameObject.SetActive(result == CornResult.Perfect);
            perfectButton.gameObject.SetActive(result != CornResult.Perfect);
            leftOkButton.gameObject.SetActive(result == CornResult.Good);
            destructionButton.gameObject.SetActive(result == CornResult.Failure);
        });
        
        perfectResultObject.SetActive(result == CornResult.Perfect);
        goodResultObject.SetActive(result == CornResult.Good);
        failureResultObject.SetActive(result == CornResult.Failure);
        
        smokeEffect.SetActive(result == CornResult.Failure);
        glitterEffect.SetActive(result == CornResult.Perfect);

        detailObject.SetActive(result != CornResult.Failure);
        explainObject.SetActive(result == CornResult.Good);
        explainWithRarityObject.SetActive(result == CornResult.Perfect);
    }

    private void AddStock(ProductData productData, ProductRarity rarity = ProductRarity.Normal)
    {
        var gameData = GameDataManager.GameData;
        // 店頭の空きに追加
        var remain = productData.volume;
        var shopSpace = Market.ShopStockCount - gameData.ShopStock.Count;
        var stockCount = Mathf.Min(shopSpace, remain);
        gameData.ShopStock.AddRange(Enumerable.Repeat(productData.id, stockCount));
        remain -= stockCount;

        // 空タンク並び替え
        gameData.StorageTanks = gameData.StorageTanks.OrderBy(tank => tank.IsEmpty).ToList();
        // 空きのタンクを確認
        gameData.StorageTanks
            .Select((tank, i) => (tank, i))
            .Where(x => x.tank.IsEmpty || x.tank.FlavorId == productData.id && !x.tank.IsFull)
            .Select(x => (x.i, space: x.tank.Capacity - x.tank.Stock))
            .OrderBy(x => x.space)
            .ToList()
            .ForEach(x =>
            {
                if (remain == 0)
                {
                    return;
                }
                // タンクが空ならフレーバー設定
                if (gameData.StorageTanks[x.i].IsEmpty)
                {
                    gameData.StorageTanks[x.i].FlavorId = productData.id;
                }
                // タンクに追加
                stockCount = Mathf.Min(x.space, remain);
                gameData.StorageTanks[x.i].AddStock(rarity, stockCount);
                remain -= stockCount;
            });
        GameDataManager.SaveGameData();
    }
}

