using System;
using System.Collections.Generic;
using Ichni.RhythmGame;
using UnityEngine;
namespace Ichni
{
///
/// 集中式元素更新调度器。
/// 将所有 GameElement 的帧更新按 9 个阶段有序执行,
/// 替代原先分散在 EditorManager.Update()、各子管理器、MonoBehaviour.Update() 中的零散更新。
///
/// 调度器分为两个执行阶段,分别在 Update 和 LateUpdate 中调用:
///
/// TickEarly (Update, EditorManager [order -100])
/// Phase 0 TimeDuration — 判定元素激活/隐藏
/// Phase 1 Animation — 更新动画值,设置脏标记
/// Phase 2 Apply — 执行 DirtyRefresh + Transform + Color
///
/// --- Unity 执行其他 Update (包括 SplineComputer.Update [order 0]) ---
/// SplineComputer 检测 transform.hasChanged,重新采样,延迟通知订阅者。
///
/// TickLate (LateUpdate, EditorManager [order -100])
/// Phase 3 SplineRebuild — 保留占位(SplineComputer 已在 Update 中自行处理)
/// Phase 4 TrackCore — 更新轨道时间、裁剪区间
/// Phase 5 TrackFollower — CrossTrackPoint / Tracker / HeadPoint / PercentPoint
/// Phase 6 Note — 音符可见性、轨道位置、判定、特效
/// Phase 7 Effect — ParticleEmitter / TimeEffectsCollection / LookAt 旋转覆盖
/// Phase 8 Misc — SkyboxSubsetter / LowPriorityActions
///
/// 此分离设计消除了 Dreamteck Spline 的一帧延迟:
/// Phase 2 (Update) 修改 Transform → SplineComputer.Update() 检测 hasChanged 并重采样
/// → Phase 5/6 (LateUpdate) 调用 RebuildImmediate() 获取最新采样后 SetPercent()。
///
/// 所有通过调度器管理的 SplinePositioner 应设置 autoUpdate = false,
/// 由调度器在 Phase 5/6 中手动调用 RebuildImmediate() 刷新采样。
///
/// 设计要点:
/// - AnimationManager 和 TrackManager 已删除,其逻辑由各 GameElement 子类通过
/// IScheduledElement.ScheduledUpdate() 自行处理。
/// - NoteManager 因内部逻辑复杂(二分搜索、时间可逆),保留为纯 C# 类,
/// 由本调度器内部持有和驱动。
/// - Phase 0(TimeDuration)和 Phase 2(Apply)仍有 [Legacy] 内联循环,
/// 待后续将 TimeDurationSubmodule / TransformSubmodule / ColorSubmodule
/// 迁移到 IScheduledElement 后移除。
///
public class ElementUpdateScheduler
{
#region [常量] Constants
/// 阶段总数(TimeDuration..Misc,步长 10,共 9 个)
private const int PhaseCount = 9;
/// 阶段枚举值到数组索引的步长除数
private const int PhaseStep = 10;
private static readonly UpdatePhase[] AllPhases = (UpdatePhase[])Enum.GetValues(typeof(UpdatePhase));
/// TickEarly 执行的最大 Phase(含)
private const UpdatePhase EarlyPhaseCutoff = UpdatePhase.Apply;
#endregion
#region [阶段元素列表] Phase Element Lists
///
/// 每个阶段的已注册 IScheduledElement 列表。
/// 使用数组替代 Dictionary<UpdatePhase, ...>,
/// 索引通过 (int)phase / 10 直接映射,消除哈希查找开销。
///
private readonly List[] _phaseElements;
/// 将 UpdatePhase 枚举值转换为数组索引。
private static int PhaseIndex(UpdatePhase phase) => (int)phase / PhaseStep;
#endregion
#region [轨道 Spline 列表] Track Spline List
/// Phase 3 专用:需要手动重建 SplineComputer 的 Track 列表(保留供后续优化)
private readonly List