package dsp

import (
	"math"
	"testing"
	"time"

	"github.com/jan/fm-rds-tx/internal/output"
)

func TestResampleIQIdentity(t *testing.T) {
	frame := &output.CompositeFrame{
		Samples:      make([]output.IQSample, 100),
		SampleRateHz: 228000,
		Timestamp:    time.Now(),
	}
	for i := range frame.Samples {
		frame.Samples[i] = output.IQSample{I: float32(i) / 100, Q: 0}
	}
	result := ResampleIQ(frame, 228000)
	if len(result.Samples) != 100 {
		t.Fatalf("expected 100, got %d", len(result.Samples))
	}
}

func TestResampleIQUpsample(t *testing.T) {
	frame := &output.CompositeFrame{
		Samples:      make([]output.IQSample, 228),
		SampleRateHz: 228000,
		Timestamp:    time.Now(),
	}
	for i := range frame.Samples {
		phase := 2 * math.Pi * float64(i) / float64(len(frame.Samples))
		frame.Samples[i] = output.IQSample{I: float32(math.Cos(phase)), Q: float32(math.Sin(phase))}
	}
	result := ResampleIQ(frame, 528000)
	expectedLen := int(float64(228) * 528000 / 228000)
	if math.Abs(float64(len(result.Samples)-expectedLen)) > 2 {
		t.Fatalf("expected ~%d samples, got %d", expectedLen, len(result.Samples))
	}
	if result.SampleRateHz != 528000 {
		t.Fatalf("expected rate 528000, got %.0f", result.SampleRateHz)
	}
	// Verify magnitude preserved (should be ~1.0 for unit circle)
	for i := 10; i < len(result.Samples)-10; i++ {
		s := result.Samples[i]
		mag := math.Sqrt(float64(s.I)*float64(s.I) + float64(s.Q)*float64(s.Q))
		if mag < 0.9 || mag > 1.1 {
			t.Fatalf("sample %d: magnitude=%.4f", i, mag)
		}
	}
}

func TestResampleIQNil(t *testing.T) {
	if ResampleIQ(nil, 528000) != nil {
		t.Fatal("expected nil")
	}
}
