// ---------------------------------------------------------------------------
// BT.Framework
// DataTableSO.cs — DataTable의 Unity ScriptableObject 래퍼
// ---------------------------------------------------------------------------
using System.Collections.Generic;
using UnityEngine;

namespace BurningTimes.Core.Data
{
    /// <summary>
    /// <see cref="DataTable{TKey, TRow}"/> 를 담는 <see cref="ScriptableObject"/> 기반 자산.
    /// </summary>
    /// <remarks>
    /// <para>설계 문서 §3-3. 기존 <c>MasterTableSO</c> 를 본 클래스로 재설계.</para>
    /// <para>하위 타입은 <see cref="BuildRows"/> 를 구현하여 인스펙터 상에서 입력한 원본을 <typeparamref name="TRow"/>
    /// 리스트로 가공해 반환한다. <see cref="Load"/> 가 호출되면 <see cref="Table"/> 이 초기화된다.</para>
    /// <para>이벤트 통지가 필요하면 호출자가 <see cref="BurningTimes.Core.Event.EventBus.Publish{TEvent}"/> 로
    /// <see cref="DataTableLoadedEvent"/> 를 발행한다 (Data 는 Event 에 런타임 의존하지 않음).</para>
    /// </remarks>
    public abstract class DataTableSO<TKey, TRow> : ScriptableObject where TRow : IDataRow<TKey>
    {
        private DataTable<TKey, TRow> _table;

        /// <summary>로드된 테이블. <see cref="Load"/> 호출 이전에는 null.</summary>
        public DataTable<TKey, TRow> Table => _table;

        /// <summary>로드 완료 여부.</summary>
        public bool IsLoaded => _table != null;

        /// <summary>테이블을 구축한다. 이미 로드된 상태면 스킵 (명시적 재로드는 <see cref="Reload"/> 사용).</summary>
        public void Load()
        {
            if (_table != null) return;
            _table = new DataTable<TKey, TRow>(BuildRows());
        }

        /// <summary>테이블을 강제로 재구축한다.</summary>
        public void Reload()
        {
            _table = new DataTable<TKey, TRow>(BuildRows());
        }

        /// <summary>하위 타입이 행 원본을 공급한다 (인스펙터 직렬화 필드·CSV·JSON 등에서 유래).</summary>
        protected abstract IEnumerable<TRow> BuildRows();
    }
}
