using System.Collections;
using UnityEngine;

namespace OCES.Audio
{
    /// <summary>
    /// 环境音通道播放器。
    /// 与 MusicChannelPlayer 逻辑相同，但使用 AmbienceTransition 表，不涉及节拍对齐。
    /// </summary>
    public class AmbienceChannelPlayer
    {
        readonly AmbienceTransitionConfig m_transitionConfig;
        readonly MonoBehaviour m_coroutineHost;
        readonly ChannelFader m_fader;
        
        ContainerPlayHandle m_currentHandle;
        Coroutine m_transitionCoroutine;
        Coroutine m_currentFadeOutCoroutine;
        Coroutine m_currentFadeInCoroutine;
        
        uint m_currentContainerId;

        public AmbienceChannelPlayer(
            AmbienceTransitionConfig transitionConfig,
            MusicContainerPlayer player,
            MonoBehaviour coroutineHost)
        {
            this.m_transitionConfig = transitionConfig;
            this.m_coroutineHost    = coroutineHost;
            this.m_fader = new ChannelFader(player, coroutineHost);
        }

        // ─────────────────────────────────────────────
        // 公开接口
        // ─────────────────────────────────────────────

        public void SwitchTo(uint newContainerId, uint fromPathId, uint toPathId)
        {
            if (newContainerId == this.m_currentContainerId && this.m_currentHandle != null)
                return;

            AmbienceTransition transition = ResolveTransition(fromPathId, toPathId);

            if (this.m_transitionCoroutine != null)
                this.m_coroutineHost.StopCoroutine(this.m_transitionCoroutine);

            this.m_transitionCoroutine = this.m_coroutineHost.StartCoroutine(
                DoTransition(newContainerId, transition));
        }

        public void Stop()
        {
            if (this.m_transitionCoroutine != null)
                this.m_coroutineHost.StopCoroutine(this.m_transitionCoroutine);

            this.m_fader.StopCurrent();
        }

        // ─────────────────────────────────────────────
        // Transition 流程（无节拍对齐）
        // ─────────────────────────────────────────────

        IEnumerator DoTransition(uint newContainerId, AmbienceTransition transition)
        {
            if (newContainerId == this.m_fader.CurrentContainerId && this.m_fader.CurrentHandle != null) yield break; 
            // 如果等待期间被切回来了，就不淡变了
            
            if (this.m_currentFadeInCoroutine != null)
            {
                this.m_coroutineHost.StopCoroutine(this.m_currentFadeInCoroutine);
                this.m_currentFadeInCoroutine = null;
            }

            if (this.m_currentFadeOutCoroutine != null)
            {
                this.m_coroutineHost.StopCoroutine(this.m_currentFadeOutCoroutine);
                this.m_currentFadeOutCoroutine = null;
            }

            ContainerPlayHandle outgoing = this.m_fader.CurrentHandle;
            float outgoingVolume = this.m_fader.CurrentVolume;

            this.m_currentFadeOutCoroutine = this.m_coroutineHost.StartCoroutine(
                this.m_fader.FadeOutBranch(outgoing, outgoingVolume, transition));

            this.m_currentFadeInCoroutine = this.m_coroutineHost.StartCoroutine(
                this.m_fader.FadeInBranch(newContainerId, transition));
            yield return this.m_currentFadeInCoroutine;
            this.m_currentFadeInCoroutine = null;
        }

        // ─────────────────────────────────────────────
        // 工具
        // ─────────────────────────────────────────────

        AmbienceTransition ResolveTransition(uint fromPathId, uint toPathId)
        {
            // 优先精确匹配
            uint exactId = fromPathId * 1000 + toPathId;
            AmbienceTransition exact = this.m_transitionConfig.QueryById(exactId);
            if (exact != null) return exact;

            // From 为任意
            uint fromWildcard = 999u * 1000 + toPathId;
            AmbienceTransition fromWild = this.m_transitionConfig.QueryById(fromWildcard);
            if (fromWild != null) return fromWild;

            // To 为任意
            uint toWildcard = fromPathId * 1000 + 999u;
            AmbienceTransition toWild = this.m_transitionConfig.QueryById(toWildcard);
            if (toWild != null) return toWild;

            // 全通配
            const uint allWild = 999u * 1000 + 999u;
            return this.m_transitionConfig.QueryById(allWild);
        }
    }
}
