package recorder

import (
	"bytes"
	"errors"
	"log"
	"time"

	"sdr-visual-suite/internal/demod"
)

// DemodLive demodulates a recent window and returns WAV bytes.
func (m *Manager) DemodLive(centerHz float64, bw float64, mode string, seconds int) ([]byte, int, error) {
	if m == nil || m.ring == nil {
		return nil, 0, errors.New("recorder not ready")
	}
	if seconds <= 0 {
		seconds = 2
	}
	end := time.Now()
	start := end.Add(-time.Duration(seconds) * time.Second)
	segment := m.ring.Slice(start, end)
	if len(segment) == 0 {
		return nil, 0, errors.New("no iq in ring")
	}
	name := mode
	if name == "" {
		name = "NFM"
	}
	switch name {
	case "AM", "NFM", "WFM", "WFM_STEREO", "USB", "LSB", "CW":
	default:
		name = "NFM"
	}
	d := demod.Get(name)
	if d == nil {
		return nil, 0, errors.New("demodulator not found")
	}
	offset := centerHz - m.centerHz
	if bw <= 0 {
		bw = 12000
	}

	var audio []float32
	var inputRate int
	gpu := m.gpuEngine()
	if gpu != nil {
		gpuMode, useGPU := gpuModeFor(name)
		if useGPU {
			if gpuAudio, gpuRate, ok := tryGPUAudio(gpu, name, segment, offset, bw, gpuMode); ok {
				audio = gpuAudio
				inputRate = gpuRate
			}
		}
	}
	if audio == nil {
		if name == "WFM_STEREO" {
			log.Printf("gpudemod: WFM_STEREO live path using CPU stereo/RDS post-process")
		} else {
			log.Printf("gpudemod: CPU live demod fallback used (%s)", name)
		}
		audio, inputRate = demodAudioCPU(d, segment, m.sampleRate, offset, bw)
	}
	buf := &bytes.Buffer{}
	if err := writeWAVTo(buf, audio, inputRate, d.Channels()); err != nil {
		return nil, 0, err
	}
	return buf.Bytes(), inputRate, nil
}
