ProjectDDD/Assets/_DDD/_Scripts/GameUi/PopupUi/RestaurantManagementUi/RestaurantManagementUi.cs
2025-08-20 18:08:41 +09:00

276 lines
9.0 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using DDD.MVVM;
namespace DDD
{
/// <summary>
/// MVVM 패턴을 적용한 새로운 레스토랑 관리 UI
/// 기존 RestaurantManagementUi의 기능을 ViewModel과 분리하여 구현
/// </summary>
[RequireComponent(typeof(RestaurantManagementViewModel))]
public class RestaurantManagementUi : PopupUi<RestaurantUiActions, RestaurantManagementViewModel>
{
[Header("Sub Views")]
[SerializeField] private ChecklistView _checklistView;
[SerializeField] private InventoryView _inventoryView;
[SerializeField] private ItemDetailView _itemDetailView;
[SerializeField] private TodayMenuView _todayMenuView;
[SerializeField] private TodayRestaurantStateView _todayRestaurantStateView;
[Header("Tab Groups")]
[SerializeField] private TabGroupUi _sectionTabs;
[SerializeField] private TabGroupUi _menuCategoryTabs;
[SerializeField] private TabGroupUi _cookwareCategoryTabs;
[Header("Hold Progress UI")]
[SerializeField, BindTo(nameof(RestaurantManagementViewModel.NormalizedHoldProgress))]
private Image _completeBatchFilledImage;
protected override void Awake()
{
base.Awake();
SetupViewModelEvents();
}
protected override void Update()
{
base.Update();
if (_viewModel != null && _viewModel.IsHolding)
{
_viewModel.UpdateHoldProgress();
}
}
public override void Open(OpenPopupUiEvent evt)
{
base.Open(evt);
InitializeViews();
SetupTabs();
}
protected override GameObject GetInitialSelected()
{
// ViewModel의 현재 상태에 따라 초기 선택 UI 결정
var inventoryInitialSelected = _inventoryView.GetInitialSelected();
if (inventoryInitialSelected) return inventoryInitialSelected;
var menuCategoryButton = _menuCategoryTabs.GetFirstInteractableButton();
if (menuCategoryButton != null && menuCategoryButton.activeInHierarchy)
return menuCategoryButton;
var cookwareCategoryButton = _cookwareCategoryTabs.GetFirstInteractableButton();
if (cookwareCategoryButton != null && cookwareCategoryButton.activeInHierarchy)
return cookwareCategoryButton;
return null;
}
protected override void SetupBindings()
{
// Attribute 기반 자동 바인딩이 처리됨
// 추가적인 수동 바인딩이 필요한 경우 여기에 구현
}
protected override void HandleCustomPropertyChanged(string propertyName)
{
switch (propertyName)
{
case nameof(RestaurantManagementViewModel.CurrentSection):
UpdateSectionTabs();
break;
case nameof(RestaurantManagementViewModel.CurrentCategory):
UpdateCategoryTabs();
break;
}
}
private void SetupViewModelEvents()
{
if (!_viewModel) return;
_viewModel.OnBatchCompleted = HandleBatchCompleted;
_viewModel.OnChecklistFailed = HandleChecklistFailed;
_viewModel.OnMenuSectionSelected = HandleMenuSectionSelected;
_viewModel.OnCookwareSectionSelected = HandleCookwareSectionSelected;
_viewModel.OnCategoryChanged = HandleCategoryChanged;
_viewModel.OnTabMoved = HandleTabMoved;
_viewModel.OnInteractRequested = HandleInteractRequested;
_viewModel.OnCloseRequested = HandleCloseRequested;
_viewModel.OnMenuCategorySelected = HandleMenuCategorySelected;
}
private void InitializeViews()
{
_checklistView.Initalize();
_inventoryView.Initialize();
_itemDetailView.Initialize();
_todayMenuView.Initialize();
_todayRestaurantStateView.Initialize();
}
private void SetupTabs()
{
SetupCategoryTabs();
InitializeTabGroups();
SelectInitialTabs();
}
private void SetupCategoryTabs()
{
_menuCategoryTabs.UseDefaultAllowedValues();
_cookwareCategoryTabs.UseDefaultAllowedValues();
}
private void InitializeTabGroups()
{
_sectionTabs.Initialize(OnSectionTabSelected);
_menuCategoryTabs.Initialize(OnCategoryTabSelected);
_cookwareCategoryTabs.Initialize(OnCategoryTabSelected);
}
private void SelectInitialTabs()
{
_sectionTabs.SelectFirstTab();
_menuCategoryTabs.SelectFirstTab();
}
private void UpdateSectionTabs()
{
if (_viewModel == null) return;
_sectionTabs.SelectTab((int)_viewModel.CurrentSection);
}
private void UpdateCategoryTabs()
{
if (_viewModel == null) return;
switch (_viewModel.CurrentSection)
{
case SectionButtonType.Menu:
_menuCategoryTabs.SelectTab((int)_viewModel.CurrentCategory);
break;
case SectionButtonType.Cookware:
_cookwareCategoryTabs.SelectTab((int)_viewModel.CurrentCategory);
break;
}
}
// ViewModel 이벤트 핸들러들
private void HandleBatchCompleted()
{
Close();
}
private void HandleChecklistFailed()
{
var evt = GameEvents.OpenPopupUiEvent;
evt.UiType = typeof(ConfirmUi);
evt.IsCancelButtonVisible = true;
evt.NewMessageKey = "checklist_failed_message";
evt.OnConfirm = ClosePanel;
EventBus.Broadcast(evt);
}
private void HandleMenuSectionSelected()
{
_menuCategoryTabs.SelectFirstTab();
}
private void HandleCookwareSectionSelected()
{
_cookwareCategoryTabs.SelectFirstTab();
}
private void HandleCategoryChanged(InventoryCategoryType category)
{
_inventoryView.UpdateCategoryView(category);
_itemDetailView.UpdateCategory(category);
}
private void HandleTabMoved(int direction)
{
_sectionTabs.Move(direction);
}
private void HandleInteractRequested()
{
var selected = EventSystem.current.currentSelectedGameObject;
var interactable = selected?.GetComponent<IInteractableUi>();
interactable?.OnInteract();
}
private void HandleCloseRequested()
{
Close();
}
private void HandleMenuCategorySelected(InventoryCategoryType category)
{
_menuCategoryTabs.SelectTab((int)category);
}
// UI 이벤트 핸들러들 (TabGroupUi 콜백)
private void OnSectionTabSelected(int sectionValue)
{
_viewModel?.SetSection((SectionButtonType)sectionValue);
}
private void OnCategoryTabSelected(int categoryValue)
{
_viewModel?.SetCategory((InventoryCategoryType)categoryValue);
}
// 입력 처리 - ViewModel로 위임
protected override bool OnInputPerformed(RestaurantUiActions actionEnum, InputAction.CallbackContext context)
{
var isHandled = base.OnInputPerformed(actionEnum, context);
if (isHandled && _viewModel != null)
{
switch (actionEnum)
{
case RestaurantUiActions.Cancel:
_viewModel.CloseUi();
break;
case RestaurantUiActions.PreviousTab:
_viewModel.MoveTab(-1);
break;
case RestaurantUiActions.NextTab:
_viewModel.MoveTab(1);
break;
case RestaurantUiActions.Interact1:
_viewModel.InteractWithSelected();
break;
case RestaurantUiActions.Interact2:
_viewModel.StartHold();
break;
}
}
return isHandled;
}
protected override bool OnInputCanceled(RestaurantUiActions actionEnum, InputAction.CallbackContext context)
{
var isHandled = base.OnInputCanceled(actionEnum, context);
if (isHandled && _viewModel != null)
{
switch (actionEnum)
{
case RestaurantUiActions.Interact2:
_viewModel.CancelHold();
break;
}
}
return isHandled;
}
}
}