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

public class Information : MonoBehaviour
{
    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 GameObject shopInfoEnabled;
    [SerializeField] private GameObject recordEnabled;
    [SerializeField] private Button shopInfoButton;
    [SerializeField] private Button recordButton;

    [SerializeField] private ScrollRect scrollRect;
    [SerializeField] private GameObject shopInfoObject;
    [SerializeField] private GameObject recordObject;

    [SerializeField] private Transform historyTarget;
    [SerializeField] private Transform productTarget;
    [SerializeField] private Transform materialTarget;
    
    [SerializeField] private ShopHistoryItemView historyPrefab;
    [SerializeField] private HasProductItemView productPrefab;
    [SerializeField] private HasMaterialItemView materialPrefab;
    
    [SerializeField] private Text totalDayText;
    [SerializeField] private Text totalSalesText;
    [SerializeField] private Text totalCoinText;

    public static readonly string dayFormat = "{0}日";
    public static readonly string salesFormat = "{0}個";
    public static readonly string progressFormat = "{0}/{1}";
    
    [SerializeField] private Text achievementText;
    [SerializeField] private Text shopLevelText;
    [SerializeField] private Text progressText;

    private void Start()
    {
        closeButton.OnClickAsObservable().Take(1).Subscribe(_ =>
        {
            transform.SetLocalScale(0);
            backgroundAnimator.SetTrigger(CloseTrigger);
            this.CallWaitForSeconds(.25f, () =>
            {
                TransitionManager.Instance.UnloadScene(GameScenes.Information);
            });
        }).AddTo(this);
        shopInfoButton.OnClickAsObservable().Select(_ => true)
            .Merge(recordButton.OnClickAsObservable().Select(_ => false))
            .Subscribe( isShopInfo =>
            {
                shopInfoButton.gameObject.SetActive(!isShopInfo);
                shopInfoEnabled.SetActive(isShopInfo);
                shopInfoObject.SetActive(isShopInfo);
                recordButton.gameObject.SetActive(isShopInfo);
                recordEnabled.SetActive(!isShopInfo);
                recordObject.SetActive(!isShopInfo);
                scrollRect.content = (isShopInfo ? shopInfoObject.transform : recordObject.transform) as RectTransform;
                scrollRect.verticalNormalizedPosition = 1;
            }).AddTo(this);

        var gameData = GameDataManager.GameData;
        var shopLevelList = SpreadsheetDataManager.Instance.GetBaseDataList<ShopLevelData>(Const.ShopLevelDataSheet);
        shopLevelList = shopLevelList.Where(data => data.shopLevel != Const.SpecialShopLevel).ToList();
        var shopScriptList = SpreadsheetDataManager.Instance.GetBaseDataList<BrotherScriptData>(Const.ScriptDataSheet);
        var shopLevelData = shopLevelList.FirstOrDefault(data => data.shopLevel == gameData.ViewedShopLevel) ?? shopLevelList[0];
        var nextShopLevelData = shopLevelList.FirstOrDefault(data => data.shopLevel == gameData.ViewedShopLevel + 1);
        var nextLevelHeart = nextShopLevelData?.heart ?? shopLevelData.heart;
        totalDayText.text = String.Format(dayFormat, gameData.dailyLoginCount);
        totalSalesText.text = String.Format(salesFormat, gameData.TotalSales);
        totalCoinText.text = gameData.TotalAddCoin.ToString();
        achievementText.text = shopLevelData.achievement;
        shopLevelText.text = gameData.ViewedShopLevel.ToString();
        progressText.text = String.Format(progressFormat, Mathf.Min(gameData.Heart, nextLevelHeart), nextLevelHeart);

        var productList = SpreadsheetDataManager.Instance.GetBaseDataList<ProductData>(Const.ProductDataSheet);
        var materialList = SpreadsheetDataManager.Instance.GetBaseDataList<ShopData>(Const.ShopDataSheet);
        var shopStockList = gameData.ShopStock.Select(data => (data.FlavorId, data.Stock));
        var tankStockList = gameData.StorageTanks.Select(data => (data.FlavorId, data.Stock));
        var totalStockList = shopStockList.Concat(tankStockList).ToList();

        // shopLevel
        historyTarget.DestroyAllChildrens();
        var shopLevelIndex = 1;
        foreach (var levelData in shopLevelList)
        {
            var scriptList = shopScriptList.Where(data => data.id == levelData.shopLevel).ToList();
            var view = Instantiate(historyPrefab, historyTarget);
            view.SetOddBG(shopLevelIndex % 2 == 0);
            shopLevelIndex++;
            if (levelData.shopLevel > gameData.ViewedShopLevel)
            {
                view.SetUnreleased(true);
                continue;
            }
            view.SetData(levelData);
            if (scriptList.Count > 0)
            {
                view.PlayButton.ThrottleFirst(TimeSpan.FromSeconds(1f)).Subscribe(_ =>
                {
                    LocalCacheManager.Save(BrotherConversation.ScriptDataTag, scriptList);
                    TransitionManager.Instance.LoadSceneAdditive(GameScenes.Conversation);
                }).AddTo(view);
            }
            else
            {
                view.SetButtonAcive(false);
            }
        }
        
        // product
        productTarget.DestroyAllChildrens();
        if (totalStockList.Sum(data => data.Stock) == 0)
        {
            var view = Instantiate(productPrefab, productTarget);
            view.SetNoStock(true);
        }
        else
        {
            foreach (var productData in productList)
            {
                var count = totalStockList.Count(data => data.FlavorId == productData.id);
                if (count == 0)
                {
                    continue;
                }

                var view = Instantiate(productPrefab, productTarget);
                view.SetData(productData, count);
            }
        }

        // material
        materialTarget.DestroyAllChildrens();
        var totalCount = gameData.Material.Sum(data => data.Amount);
        if (totalCount == 0)
        {
            var view = Instantiate(materialPrefab, materialTarget);
            view.SetNoStock(true);
        }
        else
        {
            foreach (var materialData in gameData.Material)
            {
                if (materialData.Amount == 0)
                {
                    continue;
                }
                var view = Instantiate(materialPrefab, materialTarget);
                view.SetData(materialList.First(data => data.itemId == materialData.Id), materialData.Amount);
            }
        }
        
        shopInfoObject.SetActive(true);
        scrollRect.content = shopInfoObject.transform as RectTransform;
        LayoutRebuilder.ForceRebuildLayoutImmediate(scrollRect.content);
        scrollRect.verticalNormalizedPosition = 1;
        shopInfoButton.onClick.Invoke();
    }
}
