using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using I2.Loc;
using MyGame.Scenes.marketing.Scripts;
using MyGame.Scripts;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

public class DebugOptionManager : MonoBehaviour
{
    // シーン取得
    public static readonly string DebugPrevSceneTag = "DebugPrevScene";
    [SerializeField] private Button resetButton;
    [SerializeField] private Button backButton;
    [SerializeField] private Button resetFieldButton;
    [SerializeField] private Button resetMaterialButton;
    [SerializeField] private Button resetTankButton;
    [SerializeField] private Button refillManyProductButton;
    [SerializeField] private Button refillLittleProductButton;
    [SerializeField] private Button bulkOrderResetButton;
    [SerializeField] private Button shopLevelUpResetButton;
    [SerializeField] private Button dailyMissionResetButton;
    [SerializeField] private Button dailyMissionCompleteButton;
    [SerializeField] private Button normalMissionResetButton;
    [SerializeField] private Button autoCookCompleteButton;
    [SerializeField] private Button resetShopCustomizeButton;
    [SerializeField] private Button completeShopCustomizeButton;
    
    [Space]
    [SerializeField] private Button japaneseButton;
    [SerializeField] private Button chineseButton;
    [SerializeField] private Button englishButton;
    [SerializeField] private Button koreaButton;
    
    [SerializeField] private Toggle alwaysVideoFailToLoadToggle;
    [SerializeField] private Toggle fastGrowingToggle;
    [SerializeField] private Toggle skipTutorialToggle;
    [SerializeField] private Toggle manyWalkerToggle;
    [SerializeField] private Toggle vipRewardToggle;
    [SerializeField] private InputField coinCount;
    [SerializeField] private InputField heartCount;
    [SerializeField] private InputField shopCustomizeCoinCount;
    [SerializeField] private Dropdown shopLevelDropdown;
    [SerializeField] private Dropdown bulkOrderDropdown;
    [SerializeField] private Dropdown autoCookDropdown;
#if UNITY_EDITOR || DEVELOPMENT_BUILD
    // Start is called before the first frame update
    void Start()
    {
        var gameData = GameDataManager.GameData;
        Market.Instance.IsPause.Value = true;
        
        if (!LocalCacheManager.Exists(DebugPrevSceneTag))
        {
            TransitionManager.Instance.LoadScene(GameScenes.Main);
        }
        SoundManager.Instance.StopBGM();
        var prevScene = LocalCacheManager.Load<GameScenes>(DebugPrevSceneTag);
        resetButton.OnClickAsObservable().Subscribe(_ =>
        {
            GameDataManager.ResetData();
            TutorialManager.Instance.ResetTutorial();
            Market.Instance.SetGameData(GameDataManager.GameData);
            Market.Instance.ReShuffle(GameDataManager.GameData.ShopStock);
            Market.Instance.CheckStock(GameDataManager.GameData.ShopStock);
            if (UsayaStorageManager.LoadOrDefault(UsayaStorageFilename.Settings_Data, "DebugTutorialEnable", false))
            {
                GameDataManager.GameData.ViewedShopLevel = 1;
                GameDataManager.GameData.FinishTutorial();
            }
            TransitionManager.Instance.LoadScene(GameScenes.DebugOption);
        }).AddTo(this);
        
        backButton.OnClickAsObservable().Subscribe(_ =>
        {
            GameDataManager.SaveGameData();
            Market.Instance.IsPause.Value = false;
            TransitionManager.Instance.LoadScene(prevScene);
        });

        resetFieldButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.PlantLineDataList = new List<PlantLineData>
            {
                new PlantLineData(PlantLineType.Center, CornFieldRank.Rank1),
            };
            gameData.SeedlingDataList = new List<SeedlingProgressData>();
            gameData.MachineLevel = 1;
            gameData.CornSeed = 0;
        }).AddTo(this);

        resetMaterialButton.OnClickAsObservable().Subscribe(_ =>
        {
            // 所持素材
            gameData.Material.Clear();
            // レシピ
            gameData.MyRecipes = GetMyRecipe(gameData.ViewedShopLevel);
            // フライパン
            gameData.Pans = new[] { Const.DefaultPanId };
        }).AddTo(this);

        resetTankButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.InitTank();
        }).AddTo(this);

        refillManyProductButton.OnClickAsObservable().Subscribe(_ =>
        {
            // gameData.StorageTanks.Clear();
            // CookingResult.AddStock(new ProductData(){volume = 5, id = 1}, ProductRarity.Normal);
            // CookingResult.AddStock(new ProductData(){volume = 5, id = 1}, ProductRarity.Yellow);
            // CookingResult.AddStock(new ProductData(){volume = 5, id = 1}, ProductRarity.Copper);
            // CookingResult.AddStock(new ProductData(){volume = 5, id = 1}, ProductRarity.Silver);
            // CookingResult.AddStock(new ProductData(){volume = 5, id = 1}, ProductRarity.Gold);
            // CookingResult.AddStock(new ProductData(){volume = 5, id = 1}, ProductRarity.Rainbow);
            // CookingResult.AddStock(new ProductData(){volume = 20, id = 2}, ProductRarity.Silver);
            if (gameData.StorageTanks.Count < 2)
            {
                gameData.StorageTanks.Add(new StorageTank(){Capacity = Const.TankCapacity});
            }
            var flavor = gameData.StorageTanks[0].FlavorId;
            if (flavor < 1)
            {
                flavor = 1;
            }
            CookingResult.AddStock(new ProductData(){volume = 5, id = flavor}, ProductRarity.Normal);
            CookingResult.AddStock(new ProductData(){volume = 5, id = flavor}, ProductRarity.Yellow);
            CookingResult.AddStock(new ProductData(){volume = 5, id = flavor}, ProductRarity.Copper);
            CookingResult.AddStock(new ProductData(){volume = 5, id = flavor}, ProductRarity.Silver);
            CookingResult.AddStock(new ProductData(){volume = 10, id = 1}, ProductRarity.Copper);
            CookingResult.AddStock(new ProductData(){volume = 10, id = 1}, ProductRarity.Silver);
        }).AddTo(this);
        
        refillLittleProductButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.StorageTanks.ForEach(x => x.ClearStock());
            // CookingResult.AddStock(new ProductData(){volume = 5, id = 1}, ProductRarity.Yellow);
            CookingResult.AddStock(new ProductData(){volume = 3, id = 2}, ProductRarity.Copper);
        }).AddTo(this);

        bulkOrderResetButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.AchievedOrderLevel = 0;
            gameData.OrderIdInProgress = 0;
            gameData.CancelOrderId = 0;
            gameData.CompletedProductList.Clear();
        }).AddTo(this);

        shopLevelUpResetButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.ViewedShopLevel = 0;
        }).AddTo(this);

        dailyMissionResetButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.lastDailyMissionSetTime = DateTime.MinValue.ToBinary();
        }).AddTo(this);
        
        dailyMissionCompleteButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.dailyMissionAchievedIdArray = gameData.dailyMissionIdArray;
            gameData.dailyMissionCompleted = false;
        }).AddTo(this);
        
        normalMissionResetButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.AchievedMission.Clear();
            gameData.ResetNormalTotalCount();
        }).AddTo(this);

        autoCookCompleteButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.AutoCookFinishTime = DateTime.UtcNow.ToBinary();
        }).AddTo(this);

        resetShopCustomizeButton.OnClickAsObservable().Subscribe(_ =>
        {
            gameData.FinishedFlags &= ~TutorialFlag.ShopCustomize;
            gameData.ShopCustomizeLevel = 1;
            gameData.ShopCustomizePoint = 0;
            gameData.ShopCustomizeCoin = 0;
            gameData.ShopCustomizeSettings = new ShopCustomizeSettings();
            gameData.ShopCustomizeMyItems = new[]
            {
                Const.ShopCustomizeDefaultCartId,
                Const.ShopCustomizeDefaultDecoration1Id,
                Const.ShopCustomizeDefaultDecoration2Id,
                Const.ShopCustomizeDefaultStockId,
                Const.ShopCustomizeDefaultSignBoardId,
            };
        }).AddTo(this);

        completeShopCustomizeButton.OnClickAsObservable().Subscribe(_ =>
        {
            var shopCustomizeDataList = SpreadsheetDataManager.Instance.GetBaseDataList<ShopCustomizeData>(Const.ShopCustomizeDataSheet);
            var shopCustomizeLevelList = SpreadsheetDataManager.Instance.GetBaseDataList<ShopCustomizeLevelData>(Const.ShopCustomizeLevelDataSheet);
            var maxLevelData = shopCustomizeLevelList.Last();
            
            gameData.ShopCustomizeLevel = maxLevelData.level;
            gameData.ShopCustomizePoint = maxLevelData.point;
            gameData.ShopCustomizeMyItems = gameData.ShopCustomizeMyItems
                .Union(shopCustomizeDataList.Select(data => data.id)).ToArray();
        }).AddTo(this);
        
        // switch lang

        japaneseButton.OnClickAsObservable().Subscribe(_ =>
        {
            LocalizationManager.CurrentLanguage = "Japanese";
        }).AddTo(this);
        
        chineseButton.OnClickAsObservable().Subscribe(_ =>
        {
            LocalizationManager.CurrentLanguage = "Chinese";
        }).AddTo(this);
        
        englishButton.OnClickAsObservable().Subscribe(_ =>
        {
            LocalizationManager.CurrentLanguage = "English";
        }).AddTo(this);

        koreaButton.OnClickAsObservable().Subscribe(_ =>
        {
            LocalizationManager.CurrentLanguage = "Korean";
        }).AddTo(this);

        coinCount.text = $"{gameData.Coin}";
        coinCount.OnValueChangedAsObservable().Subscribe(x =>
        {
            gameData.Coin = Int32.Parse(x);
        }).AddTo(this);
        
        heartCount.text = $"{gameData.Heart}";
        heartCount.OnValueChangedAsObservable().Subscribe(x =>
        {
            gameData.Heart = Int32.Parse(x);
        }).AddTo(this);
        
        shopCustomizeCoinCount.text = $"{gameData.ShopCustomizeCoin}";
        shopCustomizeCoinCount.OnValueChangedAsObservable().Subscribe(x =>
        {
            gameData.ShopCustomizeCoin = Int32.Parse(x);
        }).AddTo(this);
        
        /*
         * 店舗レベル指定
         * レベルアップ表示後の状態
         * ハートの数は気にせずに変更可能（だたしハートの数が多ければ即レベルアップ演出となる）
         * ショップ購入のレシピは保持される
         */
        shopLevelDropdown.ClearOptions();
        var shopLevelList = SpreadsheetDataManager.Instance.GetBaseDataList<ShopLevelData>(Const.ShopLevelDataSheet);
        shopLevelDropdown.AddOptions(shopLevelList.Where(data => data.shopLevel != Const.SpecialShopLevel).Select(data => data.shopLevel.ToString()).ToList());
        shopLevelDropdown.value = gameData.ViewedShopLevel - 1;
        shopLevelDropdown.OnValueChangedAsObservable()
            .Skip(1)
            .DistinctUntilChanged()
            .Subscribe(x =>
            {
                var shopLevelData = shopLevelList.First(data => data.shopLevel == x + 1);
                gameData.ViewedShopLevel = shopLevelData.shopLevel;
                gameData.Heart = shopLevelData.heart;
                gameData.MyRecipes = GetMyRecipe(shopLevelData.shopLevel);
            }).AddTo(this);

        /*
         * 現在の店舗レベルで受けられる大量注文から任意の注文を選択可能
         */
        bulkOrderDropdown.ClearOptions();
        var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
        var nextOrderList = bulkOrderList
            .Where(data => data.shopLevel <= gameData.ViewedShopLevel)
            .ToList();
        if (nextOrderList.Count > 0)
        {
            var len = nextOrderList.Count;
            var index = nextOrderList.FindIndex(data => data.id == gameData.OrderIdInProgress);
            bulkOrderDropdown.AddOptions(nextOrderList.Select(data => $"id:{data.id}").ToList());
            // 現在のIDをデフォで設定
            if (index != -1)
            {
                bulkOrderDropdown.value = index;
            }
            bulkOrderDropdown.OnValueChangedAsObservable()
                .Skip(1)
                .DistinctUntilChanged()
                .Subscribe(x =>
                {
                    // オーダー達成状況をリセット
                    gameData.DeliveredOrder.Clear();
                    gameData.AchievedOrderLevel = nextOrderList[x].shopLevel - 1;
                    // 1つ前のオーダーを現在のオーダーに設定
                    var prevOrder = nextOrderList[(len + x - 1) % len];
                    gameData.OrderIdInProgress = gameData.CancelOrderId = prevOrder.id;
                    // 即座に通知を発生
                    gameData.OrderConditionCount = 99999;
                }).AddTo(this);
        }
        
        /*
         * 自動調理レベル
         */
        autoCookDropdown.ClearOptions();
        var autoCookList = SpreadsheetDataManager.Instance.GetBaseDataList<AutoCookData>(Const.AutoCookDataSheet);
        autoCookDropdown.AddOptions(autoCookList.Select(data => data.level.ToString()).ToList());
        autoCookDropdown.value = gameData.AutoCookLevel - 1;
        autoCookDropdown.OnValueChangedAsObservable()
            .Skip(1)
            .DistinctUntilChanged()
            .Subscribe(x =>
            {
                gameData.AutoCookUsesCount = 0;
                gameData.AutoCookLevel = autoCookList[x].level;
                // level1ならチュートリアル復活
                if (gameData.AutoCookLevel == 1)
                {
                    gameData.FinishedFlags &= ~TutorialFlag.AutoCook;
                    gameData.AutoCookFinishTime = DateTime.UtcNow.ToBinary();
                    gameData.AutoCookProducts = Array.Empty<int>();
                    gameData.AutoCookUsesCount = 0;
                }
            }).AddTo(this);


        // debugfielddata
        // gameData.PlantLines = new List<PlantLineData>
        // {
        //     new PlantLineData(PlantLineType.Top, CornFieldRank.Rank2),
        //     new PlantLineData(PlantLineType.Center, CornFieldRank.Rank1),
        //     new PlantLineData(PlantLineType.Bottom, CornFieldRank.Rank3)
        // };

        alwaysVideoFailToLoadToggle.isOn = UsayaStorageManager.LoadOrDefault(UsayaStorageFilename.Settings_Data, "DebugAlwaysVideoFailToLoad", false);
        alwaysVideoFailToLoadToggle.OnValueChangedAsObservable().Subscribe(x =>
        {
            UsayaStorageManager.Save(UsayaStorageFilename.Settings_Data, "DebugAlwaysVideoFailToLoad", x);
        }).AddTo(this);
        fastGrowingToggle.isOn = UsayaStorageManager.LoadOrDefault(UsayaStorageFilename.Settings_Data, "DebugFastGrowing", false);
        fastGrowingToggle.OnValueChangedAsObservable().Subscribe(x =>
        {
            UsayaStorageManager.Save(UsayaStorageFilename.Settings_Data, "DebugFastGrowing", x);
        }).AddTo(this);
        manyWalkerToggle.isOn = UsayaStorageManager.LoadOrDefault(UsayaStorageFilename.Settings_Data, "DebugManyWalker", false);
        manyWalkerToggle.OnValueChangedAsObservable().Subscribe(x =>
        {
            UsayaStorageManager.Save(UsayaStorageFilename.Settings_Data, "DebugManyWalker", x);
        }).AddTo(this);
        skipTutorialToggle.isOn = UsayaStorageManager.LoadOrDefault(UsayaStorageFilename.Settings_Data, "DebugTutorialEnable", false);
        skipTutorialToggle.OnValueChangedAsObservable().Subscribe(x =>
        {
            UsayaStorageManager.Save(UsayaStorageFilename.Settings_Data, "DebugTutorialEnable", x);
        }).AddTo(this);
        vipRewardToggle.isOn = gameData.vipCustomerFirstOpen;
        vipRewardToggle.OnValueChangedAsObservable().Subscribe(x =>
        {
            gameData.vipCustomerFirstOpen = x;
            gameData.vipCustomerLimitTime = (x ? DateTime.UtcNow.AddSeconds(60f) : DateTime.UtcNow).ToBinary();
        }).AddTo(this);
    }
    
   private static int[] GetMyRecipe(int level)
    {
        var shopLevelList = SpreadsheetDataManager.Instance.GetBaseDataList<ShopLevelData>(Const.ShopLevelDataSheet);
        return GameDataManager.GameData.MyRecipes.Except(shopLevelList.Select(data => data.id))
            .Union(shopLevelList.Where(data => data.shopLevel <= level).Select(data => data.id))
            .ToArray();
    }
#endif
}
