#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;
namespace SHI.Modal
{
///
/// 계층적 트리 구조를 표시하는 커스텀 UI Toolkit 컴포넌트입니다.
///
/// 개요:
///
/// TreeList는 Unity UI Toolkit의 TreeView를 래핑하여 검색, 가시성 토글,
/// 닫기 기능 등을 제공하는 재사용 가능한 컴포넌트입니다.
/// UXML 파일(TreeList.uxml, TreeListItem.uxml)과 함께 사용됩니다.
///
///
/// 주요 기능:
///
/// - 계층적 트리 구조 표시 (펼치기/접기 지원)
/// - 실시간 검색 필터링
/// - 항목별 가시성(눈 아이콘) 토글
/// - 선택 이벤트 처리
///
///
/// UXML에서 사용:
///
/// <SHI.Modal.TreeList name="tree-list" />
///
///
/// 코드에서 사용:
///
/// var treeList = root.Q<TreeList>();
/// treeList.OnSelectionChanged += (item) => Debug.Log($"선택: {item.name}");
/// treeList.OnVisibilityChanged += (item) => model.SetActive(item.id, item.IsVisible);
/// treeList.SetData(treeItems);
///
///
/// 관련 리소스:
///
/// - Resources/SHI/Modal/TreeList.uxml - 메인 레이아웃
/// - Resources/SHI/Modal/TreeListItem.uxml - 개별 항목 템플릿
///
///
[UxmlElement]
public partial class TreeList : VisualElement
{
#region 상수 (Constants)
/// 메인 UXML 파일 경로 (Resources 폴더 기준)
private const string UXML_PATH = "SHI/Modal/TreeList";
/// 개별 항목 템플릿 UXML 파일 경로 (Resources 폴더 기준)
private const string ITEM_UXML_PATH = "SHI/Modal/TreeListItem";
#endregion
#region UI 컴포넌트 참조 (UI Component References)
/// 검색어 입력 필드
private TextField? _searchField;
/// Unity UI Toolkit의 TreeView 컴포넌트
private TreeView? _treeView;
/// 트리 리스트 닫기 버튼
private Button? _closeButton;
/// 검색어 지우기 버튼
private Button? _clearButton;
#endregion
#region 내부 데이터 (Internal Data)
///
/// 개별 항목 UI를 생성할 때 사용하는 UXML 템플릿입니다.
/// 생성자에서 한 번만 로드하여 재사용합니다.
///
private VisualTreeAsset _itemTemplate;
///
/// 원본 루트 데이터입니다.
/// 검색 필터 해제 시 원래 데이터로 복원하는 데 사용됩니다.
///
private List _originalRoots = new();
///
/// TreeView에 바인딩되는 데이터 소스입니다.
/// TreeViewItemData는 Unity의 TreeView가 요구하는 래퍼 타입입니다.
///
private List>? _rootData;
///
/// 항목 ID 자동 생성을 위한 시드 값입니다.
/// SetData() 호출 시 id가 0인 항목에 순차적으로 ID를 할당합니다.
///
private int _idSeed = 1;
///
/// 이전에 선택된 항목입니다.
/// 선택 해제 이벤트 발송에 사용됩니다.
///
private TreeListItemData? _previouslySelectedItem;
#endregion
#region 외부 이벤트 (Public Events)
///
/// 항목의 가시성(눈 아이콘)이 변경될 때 발생합니다.
/// 3D 모델의 GameObject 활성화/비활성화에 연동합니다.
///
public event Action OnVisibilityChanged;
///
/// 항목 선택 상태가 변경될 때 발생합니다.
/// 선택 및 선택 해제 모두에서 발생하며, item.isSelected로 구분합니다.
///
public event Action OnSelectionChanged;
///
/// 트리 리스트가 닫힐 때(숨겨질 때) 발생합니다.
/// 닫기 버튼 클릭 시 트리거됩니다.
///
public event Action OnClosed;
#endregion
#region 생성자 (Constructor)
///
/// TreeList 컴포넌트를 초기화합니다.
/// UXML 템플릿을 로드하고 내부 컴포넌트를 설정합니다.
///
public TreeList()
{
// 1. 메인 UXML 로드 및 복제
// CloneTree(this)로 UXML 내용이 이 클래스의 자식으로 추가됨
var visualTree = Resources.Load(UXML_PATH);
if (visualTree == null)
{
Debug.LogError($"[TreeMenu] UXML not found at: {UXML_PATH}");
return;
}
visualTree!.CloneTree(this);
// 2. 항목 템플릿 UXML 로드 (성능을 위해 미리 로드)
_itemTemplate = Resources.Load(ITEM_UXML_PATH);
if (_itemTemplate == null)
{
Debug.LogError($"[TreeMenu] Item UXML not found at: {ITEM_UXML_PATH}");
return;
}
// 3. 자식 요소 참조 획득 (UXML의 name 속성으로 찾음)
_searchField = this.Q("search-field");
_treeView = this.Q("main-tree-view");
_closeButton = this.Q