package app

import (
	"context"
	"encoding/binary"
	"fmt"
	"path/filepath"
	"time"

	cfgpkg "github.com/jan/fm-rds-tx/internal/config"
	offpkg "github.com/jan/fm-rds-tx/internal/offline"
	"github.com/jan/fm-rds-tx/internal/output"
	"github.com/jan/fm-rds-tx/internal/platform"
)

func RunSimulatedTransmit(cfg cfgpkg.Config, outPath string, duration time.Duration) (string, error) {
	if outPath == "" {
		outPath = filepath.Join("build", "sim", "simulated-soapy.iqf32")
	}
	fileBackend, err := output.NewFileBackend(outPath, binary.LittleEndian, output.BackendInfo{
		Name: "simulated-soapy-file", Description: "simulated soapy sink to file",
	})
	if err != nil { return "", err }
	defer fileBackend.Close(context.Background())

	soapyCfg := platform.SoapyConfig{
		BackendConfig: output.BackendConfig{
			SampleRateHz: float64(cfg.FM.CompositeRateHz), Channels: 2,
			IQLevel: float32(cfg.FM.OutputDrive),
		},
		Driver: "simulated", Device: cfg.Backend.Device,
		CenterFreqHz: cfg.FM.FrequencyMHz * 1_000_000,
		Simulated: true, SimulationPath: outPath,
	}
	driver := platform.NewSimulatedDriver(fileBackend)
	backend := platform.NewSoapyBackend(soapyCfg, driver)
	if err := backend.Configure(context.Background(), soapyCfg.BackendConfig); err != nil { return "", err }
	if err := driver.Start(context.Background()); err != nil { return "", err }

	gen := offpkg.NewGenerator(cfg)
	frame := gen.GenerateFrame(duration)
	if _, err := backend.Write(context.Background(), frame); err != nil { return "", err }
	if err := backend.Flush(context.Background()); err != nil { return "", err }
	_ = driver.Stop(context.Background())

	return fmt.Sprintf("simulated transmit: backend=%s output=%s duration=%s input=%s freq=%.1fMHz rate=%d",
		backend.Info().Name, outPath, duration, inputLabel(cfg), cfg.FM.FrequencyMHz, cfg.FM.CompositeRateHz), nil
}

func inputLabel(cfg cfgpkg.Config) string {
	if cfg.Audio.InputPath != "" { return cfg.Audio.InputPath }
	return "tones"
}
