using System;
using System.Collections.Generic;
using System.Linq;
using I2.Loc;
using UnityEngine;

public enum ItemCategory
{
    Material = 1,
    Recipe = 2,
    Pan = 3,
    Special = 9999,
}

public enum ShopItemType
{
    Consumable = 1,
    NonConsumable = 2,
}

public enum ProductRarity
{
    Normal = 1,
    Yellow = 2,
    Copper = 3,
    Silver = 4,
    Gold = 5,
    Rainbow = 6,
}

public enum CornFieldUpgradeType
{
    FieldTop = 1,
    FieldCenter = 2,
    FieldBottom = 3,
    Machine = 4,
}

public enum ProductViewType
{
    Default = 1,
    BulkOrder = 2,
}

public enum MissionCategory
{
    Normal = 1,
    Daily = 2,
}

public enum MissionCondition
{
    CornCount = 1,
    CustomerCount = 2,
    SalesCount = 3,
    RareSalesCount = 4,
    CoinConsumeCount = 5,
    RecipeCount = 6,
    BulkOrderDeliveredCount = 7,
    SaltSalesCount = 8,
    RareSaltSalesCount = 9,
    CaramelSalesCount = 10,
    RareCaramelSalesCount = 11,
    PepperSalesCount = 12,
    RarePepperSalesCount = 13,
    HoneySalesCount = 14,
    RareHoneySalesCount = 15,
    CheeseSalesCount = 16,
    RareCheeseSalesCount = 17,
    SoysourceSalesCount = 18,
    RareSoysourceSalesCount = 19,
    StrawberrySalesCount = 20,
    RareStrawberrySalesCount = 21,
    GreenteaSalesCount = 22,              
    RareGreenteaSalesCount = 23,
    ChocolateSalesCount = 24,
    RareChocolateSalesCount = 25,
    NoriSaltSalesCount = 26,
    RareNoriSaltSalesCount = 27,
    ButterSoysourceSalesCount = 28,
    RareButterSoysourceSalesCount = 29,
    PepperCheeseSalesCount = 30,
    RarePepperCheeseSalesCount = 31,
    SaltCaramelSalesCount = 32,
    RareSaltCaramelSalesCount = 33,
    NoriButterSalesCount = 34,
    RareNoriButterSalesCount = 35,
    MilkChocolateSalesCount = 36,
    RareMilkChocolateSalesCount = 37,
    CaramelCheeseSalesCount = 38,
    RareCaramelCheeseSalesCount = 39,
    HoneyButterSalesCount = 40,
    RareHoneyButterSalesCount = 41,
    GreenteaMilkSalesCount = 42,
    RareGreenteaMilkSalesCount = 43,
    StrawberryChocolaSalesCount = 44,
    RareStrawberryChocolateSalesCount = 45,
    NoriSoysourceSalesCount = 46,
    RareNoriSoysourceSalesCount = 47,
    SaltButterSalesCount = 48,
    RareSaltButterSalesCount = 49,
    StrawberryMilkSalesCount = 50,
    RareStrawberryMilkSalesCount = 51,
    SaltChocolateSalesCount = 52,
    RareSaltChocolateSalesCount = 53,
    ChocolateGreenteaSalesCount = 54,
    RareChocolateGreenteaSalesCount = 55,
    WatchVideo = 56,
    VipCustomer = 57,
    UseFertilizer = 58,
    UseAdWalker = 59,
    UseAutoCook = 60,
}

public enum MissionRewardType
{
    Coin = 1,
    ShopCustomizeCoin = 2,
}

public enum BlueFaceType
{
    Normal = 1,
    CloseEye = 2,
    Happy = 3,
    Cheer = 4,
    Sweat = 5,
    Question = 6,
    Surprise = 7,
    Tired = 8,
    Smile = 9,
}

public enum PinkFaceType
{
    Normal = 1,
    Smile = 2,
    Happy = 3,
    Cheer = 4,
    Sweat = 5,
    Question = 6,
    Surprise = 7,
}

public enum BrotherType
{
    Blue = 1,
    Pink = 2,
    Both = 3,
}

public enum ShopCustomizeCategory
{
    Category1 = 1, // メイン看板
    Category2 = 2, // 飾り付け
    Category3 = 3, // 店本体
    Category4 = 4, // 在庫メーター
    Category5 = 5, // 立て看板
    // Category6 = 6, // 背景
}

public enum ShopCustomizeBonusCategory
{
    Sales = 1,
    Customer = 2,
    AdWalker = 3,
}

public enum ScrollGameDifficulty
{
    Easy = 1,
    Normal = 2,
    Hard = 3,
}

[Serializable]
public sealed class MissionData
{
    public int id;
    public int category;
    public int shopLevel;
    public int condition;
    public int count;
    public int rewardType;
    public int reward;
    public string text;
    public MissionCategory Category => (MissionCategory) category;
    public MissionCondition Condition => (MissionCondition) condition;
    public MissionRewardType RewardType => (MissionRewardType) rewardType;
    public string Text => LocalizationManager.GetTranslation($"Mission/MissionText{id:0000}");
}

[Serializable]
public sealed class RarityData
{
    public int id;
    public float bulkOrderBonus;
    public string text;
    public string Text => LocalizationManager.GetTranslation($"Item/RarityText{id:0000}");
    public ProductRarity Rarity => (ProductRarity)id;
}

[Serializable]
public sealed class PanData
{
    public int id;
    public string name;
    public string text;
    public int rarity;
    public string prefabName;
    public float panFactor;
    public float deadZone;
    public float baseIncreaseSpeed;
    public float coldIncreaseSpeed;
    public float hotIncreaseSpeed;
    public float maxDecreaseSpeed;
    public float yellowSize;
    public float randomRange;
    public string Name => LocalizationManager.GetTranslation($"Item/PanName{id:0000}");
    public string Text => LocalizationManager.GetTranslation($"Item/PanText{id:0000}");
    public ProductRarity Rarity => (ProductRarity)rarity;
    public Transform GetPrefab()
    {
        return Resources.Load<Transform>("Pans/" + prefabName);
    }
    public RectTransform GetIconPrefab()
    {
        return Resources.Load<RectTransform>("MaterialIcons/" + prefabName);
    }
}

[Serializable]
public sealed class FieldUpgradeData
{
    public int type;
    public int level;
    public int price;
    public int harvested;
    public string prefabName;
    public CornFieldUpgradeType Type => (CornFieldUpgradeType) type;

    public RectTransform GetIconPrefab()
    {
        return Resources.Load<RectTransform>("MachineIcons/" + prefabName);
    }

    public Animator GetPrefab()
    {
        return Resources.Load<Animator>("Machines/" + prefabName);
    }
    public static CornFieldUpgradeType PlantTypeToUpgradeType(PlantLineType lineType)
    {
        switch (lineType)
        {
            case PlantLineType.Top:
                return CornFieldUpgradeType.FieldTop;
            case PlantLineType.Center:
                return CornFieldUpgradeType.FieldCenter;
            case PlantLineType.Bottom:
                return CornFieldUpgradeType.FieldBottom;
            default:
                throw new ArgumentOutOfRangeException(nameof(lineType), lineType, null);
        }
    }
}

[Serializable]
public sealed class ProductData 
{
    public int id;
    public string name;
    public int shopLevel;
    public int price;
    public int volume;
    public string text;
    public int material1Id;
    public int material2Id;
    public int material3Id;
    public int material1Count;
    public int rarity1Price;
    public int rarity2Price;
    public int rarity3Price;
    public int rarity4Price;
    public int rarity5Price;
    public int rarity6Price;
    // public int cookingType;
    public string prefabName;
    public string Name => LocalizationManager.GetTranslation($"Item/ProductName{id:0000}");
    public string Text => LocalizationManager.GetTranslation($"Item/ProductText{id:0000}");
    private List<(int id, int amount)> materialList;
    public List<(int id, int amount)> MaterialList
    {
        get
        {
            if (materialList == null)
            {
                ChangeAmount(1);
            }
            return materialList;
        }
    }

    public ProductData(){}
    public ProductData(ProductData productData, int value)
    {
        id = productData.id;
        name = productData.name;
        shopLevel = productData.shopLevel;
        price = productData.price;
        volume = productData.volume;
        text = productData.text;
        material1Id = productData.material1Id;
        material2Id = productData.material2Id;
        material3Id = productData.material3Id;
        material1Count = productData.material1Count;
        prefabName = productData.prefabName;
        ChangeAmount(value);
    }

    private void ChangeAmount(int value)
    {
        materialList = new List<(int id, int amount)>
        {
            (material1Id, material1Count * value),
            (material2Id, 1 * value),
            (material3Id, 1 * value),
        };
    }

    public int GetMaterialCount()
    {
        return materialList.Count(material => material.id != Const.NotSetMaterialId);
    }

    public int GetRarityPrice(ProductRarity rarity)
    {
        switch (rarity)
        {
            case ProductRarity.Normal:
                return rarity1Price;
            case ProductRarity.Yellow:
                return rarity2Price;
            case ProductRarity.Copper:
                return rarity3Price;
            case ProductRarity.Silver:
                return rarity4Price;
            case ProductRarity.Gold:
                return rarity5Price;
            case ProductRarity.Rainbow:
                return rarity6Price;
            default:
                throw new ArgumentOutOfRangeException(nameof(rarity), rarity, null);
        }
    }
    
    public Transform GetIconPrefab()
    {
        return Resources.Load<Transform>("PopcornIcons/" + (string.IsNullOrEmpty(prefabName) ? "package_salt" : prefabName));
    }
    public Transform GetLargePrefab()
    {
        return Resources.Load<Transform>("PopcornLargeIcons/" + (string.IsNullOrEmpty(prefabName) ? "package_salt" : prefabName));
    }
    
    public MarketPopcornView GetMarketPrefab()
    {
        return Resources.Load<MarketPopcornView>("Popcorns/" + (string.IsNullOrEmpty(prefabName) ? "package_salt" : prefabName));
    }
}

[Serializable]
public sealed class BulkOrderData
{
    public int id;
    public int shopLevel;
    public int maxOrder;
    public int firstOrderCondition;
    public int retryCondition;
    public int productId1;
    public int count1;
    public int productId2;
    public int count2;
    public int productId3;
    public int count3;
    public int rewardCoin;
    public int rewardHeart;
}

[Serializable]
public sealed class BulkOrderTextData
{
    public int id;
    public int shopLevel;
    public string requestText;
    public string thanksText;
    public string RequestText => LocalizationManager.GetTranslation($"Item/BulkOrderRequestText{id:0000}");
    public string ThanksText => LocalizationManager.GetTranslation($"Item/BulkOrderThanksText{id:0000}");
}

[Serializable]
public sealed class ShopLevelData
{
    public int id;
    public int shopLevel;
    public int heart;
    public int customer;
    public string achievement;
    public string Achievement => LocalizationManager.GetTranslation($"Item/ShopLevelText{id:0000}");
}

[Serializable]
public sealed class BrotherScriptData
{
    public int scriptId;
    public int id;
    public string text;
    public int brother;
    public int blueFace;
    public int pinkFace;
    public string Text => LocalizationManager.GetTranslation($"Script/BrotherScript{scriptId}");
    public BrotherType Brother => (BrotherType) brother;
    public BlueFaceType BlueFace => (BlueFaceType) blueFace;
    public PinkFaceType PinkFace => (PinkFaceType) pinkFace;
}

[Serializable]
public sealed class ShopData {
    public int id;
    public int itemId;
    public string name;
    public int price;
    public string text;
    public int category;
    public int consumeType;
    public string prefabName;
    public string Name => LocalizationManager.GetTranslation($"Item/MaterialName{id:0000}");
    public string Text => LocalizationManager.GetTranslation($"Item/MaterialText{id:0000}");
    public ItemCategory Category => (ItemCategory)category;
    public ShopItemType ConsumeType => (ShopItemType)consumeType;

    public Transform GetPrefab()
    {
        return Resources.Load<Transform>("Materials/" + (string.IsNullOrEmpty(prefabName) ? "salt" : prefabName));
    }
    public Transform GetIconPrefab()
    {
        return Resources.Load<Transform>("MaterialIcons/" + (string.IsNullOrEmpty(prefabName) ? "corn" : prefabName));
    }
}

[Serializable]
public sealed class AutoCookData {
    public int id;
    public int level;
    public int duration;
    public int earnCount;
    public int clearCount;
}

[Serializable]
public sealed class ShopCustomizeData {
    public int id;
    public int level;
    public int category;
    public int price;
    public int point;
    public string prefabName;
    public string Name => LocalizationManager.GetTranslation($"Item/ShopCustomizeName{id:0000}");
    public string Text => LocalizationManager.GetTranslation($"Item/ShopCustomizeText{id:0000}");
    public ShopCustomizeCategory Category => (ShopCustomizeCategory)category;

    public Transform GetPrefab()
    {
        return Resources.Load<Transform>($"ShopCustomize/{GetCategoryString(Category)}_{prefabName}");
    }
    
    public Transform GetIconPrefab()
    {
        return Resources.Load<Transform>($"ShopCustomizeIcons/{GetCategoryString(Category)}_{prefabName}");
    }

    private string GetCategoryString(ShopCustomizeCategory category)
    {
        switch (category)
        {
            case ShopCustomizeCategory.Category1:
                return "Signboard";
            case ShopCustomizeCategory.Category2:
                return "Decoration1";
            case ShopCustomizeCategory.Category3:
                return "Cart";
            case ShopCustomizeCategory.Category4:
                return "Stock";
            case ShopCustomizeCategory.Category5:
                return "Decoration2";
            default:
                throw new ArgumentOutOfRangeException(nameof(category), category, null);
        }
    }
}

[Serializable]
public sealed class ShopCustomizeLevelData
{
    public int id;
    public int level;
    public int point;
}

[Serializable]
public sealed class ShopCustomizeBonusData
{
    public int id;
    public int level;
    public int bonusLevel;
    public int category;
    public int value;
    public ShopCustomizeBonusCategory Category => (ShopCustomizeBonusCategory)category;
}

[Serializable]
public sealed class ScrollGamePlaceData
{
    public int id;
    public int placeId;
    public int needScore;
    public int itemId;
    public int recipeId;
    public int customizeId;
}

[Serializable]
public sealed class ScrollGameStageData
{
    public int id;
    public int placeId;
    public int difficulty;
    public int needScore;
    public string beginPrefabName;
    public string randomPrefabName;
}