package handler

import (
	"time"

	"github.com/qy/hw-ws-service/internal/audio"
	"github.com/qy/hw-ws-service/internal/connection"
)

// SendOpusStream 将 Opus 帧列表按 60ms/帧的节奏流控发送给硬件。
//
// 流控策略：
//  1. 预缓冲：前 PreBufferCount 帧立即发送，减少硬件首帧延迟
//  2. 时序流控：按 (帧序号 × 60ms) 计算期望发送时间，select 等待
//  3. 打断：监听 abortCh，收到关闭信号立即返回
func SendOpusStream(conn *connection.Connection, frames [][]byte, abortCh <-chan struct{}) {
	if len(frames) == 0 {
		return
	}

	startTime := time.Now()
	playedMs := 0

	// 阶段1：预缓冲，快速发送前 N 帧
	pre := audio.PreBufferCount
	if pre > len(frames) {
		pre = len(frames)
	}
	for _, f := range frames[:pre] {
		select {
		case <-abortCh:
			return
		default:
		}
		conn.SendBinary(f) //nolint:errcheck // 连接断开时下一次 ReadMessage 会返回错误
	}
	playedMs = pre * audio.FrameDurationMs

	// 阶段2：时序流控
	for _, f := range frames[pre:] {
		expectedAt := startTime.Add(time.Duration(playedMs) * time.Millisecond)
		delay := time.Until(expectedAt)

		if delay > 0 {
			select {
			case <-time.After(delay):
				// 到达预期发送时间，继续
			case <-abortCh:
				return
			}
		}

		// delay <= 0：处理比预期慢，追赶进度，直接发送
		select {
		case <-abortCh:
			return
		default:
		}

		conn.SendBinary(f) //nolint:errcheck
		playedMs += audio.FrameDurationMs
	}
}
