package ca.ksamad.encore.ui

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp

/**
 * A row of little rounded pills describing an audio format — sample rate, bit depth, and channel
 * layout (e.g. "44.1 kHz", "16-bit", "Stereo"). Shared by now-playing (the live stream) and album
 * detail (an album's stored format). Renders nothing when [pills] is empty.
 */
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun AudioFormatPills(
    pills: List<String>,
    modifier: Modifier = Modifier,
) {
    if (pills.isEmpty()) return
    FlowRow(
        modifier = modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(6.dp, Alignment.CenterHorizontally),
        verticalArrangement = Arrangement.spacedBy(6.dp),
    ) {
        pills.forEach { pill ->
            Text(
                text = pill,
                style = MaterialTheme.typography.labelSmall,
                color = MaterialTheme.colorScheme.onSecondaryContainer,
                modifier =
                    Modifier.clip(RoundedCornerShape(50))
                        .background(MaterialTheme.colorScheme.secondaryContainer)
                        .padding(horizontal = 10.dp, vertical = 4.dp),
            )
        }
    }
}

/**
 * Parse an MPD audio-format string, `samplerate:bits:channels` (e.g. `"44100:16:2"`), into pill
 * labels. The middle token can be `f` (float) or `dsd` instead of a bit depth. Only well-formed
 * parts appear; a null/garbage input yields an empty list.
 */
fun audioFormatPills(format: String?): List<String> {
    val parts = format?.split(":")?.takeIf { it.size >= 3 } ?: return emptyList()
    return buildList {
        parts[0].toIntOrNull()?.let { add(formatSampleRate(it)) }
        formatSampleFormat(parts[1])?.let { add(it) }
        formatChannels(parts[2])?.let { add(it) }
    }
}

private fun formatSampleRate(hz: Int): String {
    val khz = hz / 1000.0
    val value = if (khz % 1.0 == 0.0) khz.toInt().toString() else "%.1f".format(khz)
    return "$value kHz"
}

private fun formatSampleFormat(token: String): String? =
    when (token) {
        "f" -> "Float"
        "dsd" -> "DSD"
        else -> token.toIntOrNull()?.let { "$it-bit" }
    }

private fun formatChannels(token: String): String? =
    when (token.toIntOrNull()) {
        null -> null
        1 -> "Mono"
        2 -> "Stereo"
        else -> "$token ch"
    }
