// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later

package space.rcmd.android.sizzle.ui.toolbox

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import space.rcmd.android.sizzle.model.ToolboxSlot
import space.rcmd.android.sizzle.ui.AppViewModel
import space.rcmd.android.sizzle.ui.components.RetroDropdown
import space.rcmd.android.sizzle.ui.theme.LocalRetro

/**
 * A modulation target: a numeric parameter on another device the LFO can drive.
 * [slotIndex] < 0 represents "no target". [encoded] is the "slotIndex:paramKey"
 * form stored in the LFO slot; [label] is what the user sees.
 */
private data class LfoTarget(val slotIndex: Int, val key: String, val label: String) {
    val encoded: String get() = if (slotIndex < 0) "" else "$slotIndex:$key"
}

/**
 * The LFO's target picker (rendered under its generated parameter list). It lists
 * every numeric parameter of every other occupied slot; choosing one wires the
 * LFO to modulate it. See [AppViewModel.setLfoTarget].
 */
@Composable
fun LfoTargetPicker(vm: AppViewModel, lfo: ToolboxSlot) {
    val c = LocalRetro.current
    @Suppress("UNUSED_VARIABLE") val rev = vm.revision

    val none = LfoTarget(-1, "", "— none —")
    val targets = buildList {
        add(none)
        vm.project.toolbox.forEachIndexed { idx, slot ->
            val type = slot.type
            if (idx == lfo.index || type == null) return@forEachIndexed
            for (spec in type.params) {
                if (spec.isEnum) continue // only continuous params are modulatable
                add(LfoTarget(idx, spec.key, "${idx + 1}:${slot.name} · ${spec.label}"))
            }
        }
    }
    val current = lfo.string("target")
    val selected = targets.firstOrNull { it.encoded == current } ?: none

    Column(Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(4.dp)) {
        RetroDropdown(
            label = "TARGET",
            options = targets,
            selected = selected,
            optionLabel = { it.label },
            onSelect = { vm.setLfoTarget(lfo, it.slotIndex, it.key) },
            modifier = Modifier.fillMaxWidth(),
        )
        Text(
            "The LFO takes over its target parameter while assigned.",
            color = c.textDim, fontFamily = FontFamily.Monospace, fontSize = 10.sp,
        )
    }
}
