package audio

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

// opusJSON 是 Django 预转码上传的 Opus JSON 文件结构。
type opusJSON struct {
	SampleRate      int      `json:"sample_rate"`
	Channels        int      `json:"channels"`
	FrameDurationMs int      `json:"frame_duration_ms"`
	Frames          []string `json:"frames"` // base64 编码的 Opus 帧
}

// FetchOpusFrames 从 OSS 下载预转码的 Opus JSON 文件，解析为原始帧列表。
// 跳过 ffmpeg 实时转码，大幅降低 CPU 消耗和首帧延迟。
func FetchOpusFrames(ctx context.Context, opusURL string) ([][]byte, error) {
	httpCtx, cancel := context.WithTimeout(ctx, 60*time.Second)
	defer cancel()

	req, err := http.NewRequestWithContext(httpCtx, http.MethodGet, opusURL, nil)
	if err != nil {
		return nil, fmt.Errorf("audio: build opus request: %w", err)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("audio: download opus json: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("audio: opus json status %d", resp.StatusCode)
	}

	body, err := io.ReadAll(io.LimitReader(resp.Body, 50*1024*1024)) // 50MB 上限
	if err != nil {
		return nil, fmt.Errorf("audio: read opus json: %w", err)
	}

	var data opusJSON
	if err := json.Unmarshal(body, &data); err != nil {
		return nil, fmt.Errorf("audio: parse opus json: %w", err)
	}

	if len(data.Frames) == 0 {
		return nil, fmt.Errorf("audio: opus json has no frames")
	}

	frames := make([][]byte, 0, len(data.Frames))
	for i, b64 := range data.Frames {
		raw, err := base64.StdEncoding.DecodeString(b64)
		if err != nil {
			return nil, fmt.Errorf("audio: decode frame %d: %w", i, err)
		}
		frames = append(frames, raw)
	}

	return frames, nil
}
