using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Localization; namespace DDD.Restaurant { public class SelectedCookSnapshot { public LocalizedString Name { get; } public LocalizedString Description { get; } public Sprite CookIcon { get; } public string CookPrice { get; } public IReadOnlyList IngredientEntries { get; } public IReadOnlyList Tastes { get; } public Material TasteMaterial { get; } public SelectedCookSnapshot(LocalizedString name, LocalizedString description, Sprite cookIcon, string cookPrice, IReadOnlyList ingredientEntries, IReadOnlyList tastes, Material tasteMaterial) { Name = name; Description = description; CookIcon = cookIcon; CookPrice = cookPrice; IngredientEntries = ingredientEntries; Tastes = tastes; TasteMaterial = tasteMaterial; } public static readonly SelectedCookSnapshot Empty = new( name: null, description: null, cookIcon: null, cookPrice: null, ingredientEntries: null, tastes: System.Array.Empty(), tasteMaterial: null); } public class CookViewModel : SimpleViewModel { private CookwareType _currentCookwareType = CookwareType.None; private List _addedCookItemSlots; private Sprite _cookwareIcon; public Sprite CookwareIcon { get => _cookwareIcon; set => SetField(ref _cookwareIcon, value); } private LocalizedString _cookwareName; public LocalizedString CookwareName { get => _cookwareName; set => SetField(ref _cookwareName, value); } private SelectedCookSnapshot _selectedCookSnapshot = SelectedCookSnapshot.Empty; public SelectedCookSnapshot SelectedCookSnapshot { get => _selectedCookSnapshot; private set => SetField(ref _selectedCookSnapshot, value); } public ItemSlotUi SelectedCookSlot { get; private set; } private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData; private RestaurantManagementState GetRestaurantManagementState() => RestaurantState.Instance.ManagementState; private int _currentCookIndex = -1; public int CurrentCookIndex { get => _currentCookIndex; set => SetField(ref _currentCookIndex, value); } private readonly Dictionary _cookIngredientSlotLookup = new(); private InventorySortType _currentSortType = InventorySortType.None; public event Action OnAddedIngredients; public GameObject GetInitialSelected() => _addedCookItemSlots[0].gameObject; public void SetCookwareType(CookwareType cookwareType) { if (_currentCookwareType == cookwareType) return; _currentCookwareType = cookwareType; var cookwareDatas = DataManager.Instance.GetDataSo().GetDataList(); var cookwareKey = cookwareDatas.Find(data => data.CookwareType == cookwareType).Id; CookwareIcon = DataManager.Instance.GetIcon(cookwareKey); CookwareName = LocalizationManager.Instance.GetLocalizedName(cookwareKey); } public void SetAddedCook(int index) { if (CurrentCookIndex == index) return; CurrentCookIndex = index; BeginUpdate(); SelectedCookSlot = _addedCookItemSlots[index]; UpdateSelectedCook(); EndUpdate(); } public void CreateAddedCookItemSlot(Transform parent) { _addedCookItemSlots = new List(parent.GetComponentsInChildren()); // Dictionary 하나로 레시피 ID와 개수를 함께 관리 var matchingRecipes = new Dictionary(); // CookwareType에 맞는 레시피들을 수집 foreach (var cookwareToRecipe in GetRestaurantManagementState().CookwareToRecipeIds) { var cookwareId = cookwareToRecipe.Key; var recipeIds = cookwareToRecipe.Value; if (DataManager.Instance.GetDataSo().TryGetDataById(cookwareId, out var cookwareData) && cookwareData.CookwareType == _currentCookwareType) { foreach (var recipeId in recipeIds) { if (matchingRecipes.ContainsKey(recipeId) == false) { // 레시피 개수 가져오기 int count = GetRestaurantManagementState().TodayFoodRecipeIds.TryGetValue(recipeId, out var foodCount) ? foodCount : GetRestaurantManagementState().TodayDrinkRecipeIds.TryGetValue(recipeId, out var drinkCount) ? drinkCount : 0; matchingRecipes[recipeId] = count; } } } } var recipeList = matchingRecipes.ToList(); for (int i = 0; i < _addedCookItemSlots.Count; i++) { ItemModel model = null; if (i < recipeList.Count) { var recipe = recipeList[i]; model = ItemViewModelFactory.CreateByItemId(recipe.Key); model?.SetCount(recipe.Value); } _addedCookItemSlots[i].Initialize(model, new AddedCookSlotUiStrategy(RecipeType.FoodRecipe)); } } public void CreateIngredientInventoryItemSlot(Transform parent) { Utils.DestroyAllChildren(parent); var models = ItemViewModelFactory.CreateRestaurantManagementInventoryItem(); _cookIngredientSlotLookup.Clear(); foreach (var model in models) { if (model.ItemType != ItemType.Ingredient) continue; var itemSlotUi = Instantiate(GetRestaurantManagementData().ItemSlotUiPrefab, parent); var slot = itemSlotUi.GetComponent(); slot.Initialize(model, new InventorySlotUiStrategy()); itemSlotUi.name = model.Id; // var interactor = itemSlotUi.GetComponent(); // if (model.ItemType == ItemType.Recipe) // { // interactor.Initialize(TodayMenuEventType.Add, new TodayMenuInteractorStrategy()); // } // else // { // if (DataManager.Instance.GetDataSo().TryGetDataById(model.Id, out var cookwareData)) // { // interactor.Initialize(TodayMenuEventType.Add, new TodayCookwareInteractorStrategy()); // } // } _cookIngredientSlotLookup[model.Id] = slot; } UpdateCookIngredient(); } private IEnumerable SortSlots(IEnumerable slots) { return _currentSortType switch { InventorySortType.NameAscending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenBy(slot => slot.Model.DisplayName), InventorySortType.NameDescending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenByDescending(slot => slot.Model.DisplayName), InventorySortType.QuantityAscending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenBy(slot => slot.Model.Count), InventorySortType.QuantityDescending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenByDescending(slot => slot.Model.Count), InventorySortType.None => slots.OrderBy(slot => slot.Model.Id), _ => slots }; } public void UpdateCookIngredient() { var filteredSlots = _cookIngredientSlotLookup.Values; var sortedSlots = SortSlots(filteredSlots); int siblingIndex = 0; foreach (var slot in sortedSlots) { var model = slot.Model; if (model.HasItem) { slot.transform.SetSiblingIndex(siblingIndex++); } } } public TasteHashTagSlotUi CreateHashTag(Transform parent) { return Instantiate(GetRestaurantManagementData().TasteHashTagSlotUiPrefab, parent, false); } private void UpdateSelectedCook() { var selectedItemModel = SelectedCookSlot.Model; string key = selectedItemModel.GetRecipeResultKey; var nameLocalizedString = LocalizationManager.Instance.GetLocalizedName(key); var descriptionLocalizedString = LocalizationManager.Instance.GetLocalizedDescription(key); var cookIcon = selectedItemModel.GetResultIcon; var cookPrice = selectedItemModel.GetPrice.ToGold(); var ingredientEntries = selectedItemModel.GetIngredients; OnAddedIngredients?.Invoke(); var tastes = selectedItemModel.GetTasteDatas; var tasteMat = selectedItemModel.RecipeType switch { RecipeType.FoodRecipe => RestaurantData.Instance.ManagementData.FoodTasteMaterial, RecipeType.DrinkRecipe => RestaurantData.Instance.ManagementData.DrinkTasteMaterial, _ => null }; SelectedCookSnapshot = new SelectedCookSnapshot( name: nameLocalizedString, description: descriptionLocalizedString, cookIcon: cookIcon, cookPrice: cookPrice, ingredientEntries: ingredientEntries, tastes: tastes, tasteMaterial: tasteMat); } } }