package dev.adriankuta.visualizer.components

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import kotlin.math.abs

/**
 * Displays simple metrics derived from the current waveform and a preview of raw bytes.
 *
 * - Waveform metrics include sample count, RMS and peak (centered around 128).
 * - Raw bytes shows the first N bytes from waveform or FFT, whichever is available.
 *
 * @param waveform Latest waveform bytes (0..255 per sample) or null if not available.
 * @param fft Latest FFT interleaved real/imag bytes or null.
 * @param modifier Compose modifier for layout.
 */
@Composable
fun MetricsSection(
    waveform: ByteArray?,
    fft: ByteArray?,
    modifier: Modifier = Modifier,
) {
    Row(modifier = modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
        Column(modifier = Modifier.weight(1f)) {
            Text("Waveform metrics", style = MaterialTheme.typography.titleSmall)
            val wf = waveform
            if (wf != null) {
                val rms = rms(wf)
                val peak = peak(wf)
                Text("Samples: ${wf.size}")
                Text("RMS: ${String.format("%.3f", rms)}")
                Text("Peak: ${String.format("%.3f", peak)}")
            } else {
                Text("No waveform yet")
            }
        }
        Column(modifier = Modifier.weight(1f)) {
            Text("Raw bytes (first 32)", style = MaterialTheme.typography.titleSmall)
            val arr = waveform ?: fft
            Text(arr?.let { firstBytesString(it, 32) } ?: "<no data>")
        }
    }
}

private fun firstBytesString(bytes: ByteArray, count: Int): String =
    bytes.take(count).joinToString(prefix = "[", postfix = "]") { it.toUByte().toString() }

private fun rms(bytes: ByteArray): Double {
    if (bytes.isEmpty()) return 0.0
    var sum = 0.0
    for (b in bytes) {
        val centered = (b.toInt() and 0xFF) - 128
        sum += centered * centered
    }
    return kotlin.math.sqrt(sum / bytes.size)
}

private fun peak(bytes: ByteArray): Double {
    var p = 0
    for (b in bytes) {
        val centered = abs(((b.toInt() and 0xFF) - 128))
        if (centered > p) p = centered
    }
    return p.toDouble()
}
