package de.tsschulz.tt_tagebuch.app.ui

import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Button
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Divider
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import de.tsschulz.tt_tagebuch.app.AppDependencies
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamCreateBody
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamUpdateBody
import de.tsschulz.tt_tagebuch.shared.api.models.Member
import de.tsschulz.tt_tagebuch.shared.api.models.MemberPlayInterestSetBody
import de.tsschulz.tt_tagebuch.shared.api.models.TeamLineupAssignmentItem
import de.tsschulz.tt_tagebuch.shared.api.models.TeamLineupUpdateBody
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

private data class TeamDraft(
    val name: String,
    val plannedLeagueName: String,
    val teamGender: String,
    val teamAgeGroup: String,
)

private fun filterAssignmentsForTeamEligibility(
    teamId: Int,
    src: List<PlanningAssignment>,
    teams: List<ClubTeamDto>,
    drafts: Map<Int, TeamDraft>,
    membersById: Map<Int, Member>,
    seasonLabel: String,
): List<PlanningAssignment> {
    val team = teams.find { it.id == teamId } ?: return src
    val d = drafts[teamId] ?: return src
    val pseudo = team.copy(
        name = d.name,
        plannedLeagueName = d.plannedLeagueName.ifBlank { null },
        teamGender = d.teamGender,
        teamAgeGroup = d.teamAgeGroup,
    )
    return TeamPlanningLogic.normalizeAssignments(
        src.filter { a ->
            if (a.teamId != teamId) return@filter true
            val m = membersById[a.memberId] ?: return@filter false
            TeamPlanningLogic.isEligible(m, pseudo, seasonLabel)
        },
    )
}

@Composable
internal fun TeamPlanningScreen(
    dependencies: AppDependencies,
    clubId: Int,
    seasonId: Int,
    seasonLabel: String,
    teams: List<ClubTeamDto>,
    canWrite: Boolean,
    onTeamsChanged: () -> Unit,
    onOpenTeamEditor: (Int) -> Unit,
    t: (String, String) -> String,
    modifier: Modifier = Modifier,
) {
    val context = LocalContext.current
    val scope = rememberCoroutineScope()

    var lineupHalf by remember { mutableStateOf(TeamPlanningLogic.defaultLineupHalf()) }
    var members by remember { mutableStateOf<List<Member>>(emptyList()) }
    var interestedIds by remember { mutableStateOf<Set<Int>>(emptySet()) }
    var assignments by remember { mutableStateOf<List<PlanningAssignment>>(emptyList()) }
    val drafts = remember { mutableStateMapOf<Int, TeamDraft>() }

    var loading by remember { mutableStateOf(true) }
    var poolSearch by remember { mutableStateOf("") }
    var addInterestMemberId by remember { mutableStateOf<Int?>(null) }
    var addInterestMenu by remember { mutableStateOf(false) }
    var markingInterest by remember { mutableStateOf(false) }
    var deleteTeamId by remember { mutableStateOf<Int?>(null) }
    var info by remember { mutableStateOf<String?>(null) }

    val membersById = remember(members) { members.associateBy { it.id } }

    LaunchedEffect(teams.map { "${it.id}:${it.name}:${it.teamGender}:${it.teamAgeGroup}" }.joinToString("|")) {
        teams.forEach { team ->
            drafts[team.id] = TeamDraft(
                name = team.name,
                plannedLeagueName = team.plannedLeagueName.orEmpty(),
                teamGender = team.teamGender?.takeIf { it.isNotBlank() } ?: "open",
                teamAgeGroup = team.teamAgeGroup?.takeIf { it.isNotBlank() } ?: "adult",
            )
        }
        val keep = teams.map { it.id }.toSet()
        drafts.keys.filter { it !in keep }.forEach { drafts.remove(it) }
    }

    suspend fun loadPlanningData() {
        loading = true
        runCatching {
            coroutineScope {
                val memJob = async(Dispatchers.IO) {
                    dependencies.membersApi.listMembers(clubId, showAll = true)
                }
                val intJob = async(Dispatchers.IO) {
                    dependencies.membersApi.listPlayInterests(clubId, seasonId, lineupHalf)
                }
                members = memJob.await()
                interestedIds = intJob.await().map { it.memberId }.toSet()

                val lineupJobs = teams.map { team ->
                    async(Dispatchers.IO) {
                        runCatching {
                            team.id to dependencies.clubTeamsApi.getLineup(team.id, lineupHalf)
                        }.getOrElse { team.id to emptyList() }
                    }
                }
                val lineups = lineupJobs.awaitAll()
                assignments = TeamPlanningLogic.normalizeAssignments(
                    lineups.flatMap { (teamId, rows) ->
                        rows.sortedBy { it.position }.mapIndexed { idx, row ->
                            PlanningAssignment(teamId = teamId, memberId = row.memberId, position = idx + 1)
                        }
                    },
                )
            }
        }.onFailure { ex ->
            if (ex !is CancellationException) {
                info = ex.message ?: t("mobile.teamLoadError", "Laden fehlgeschlagen")
            }
        }
        loading = false
    }

    LaunchedEffect(clubId, seasonId, lineupHalf, teams.map { it.id }.sorted().joinToString(",")) {
        loadPlanningData()
    }

    val poolMembers = remember(members, interestedIds, poolSearch) {
        val q = poolSearch.trim().lowercase()
        members.filter { it.id in interestedIds && it.active }
            .filter {
                if (q.isEmpty()) true
                else "${it.firstName} ${it.lastName}".lowercase().contains(q)
            }
            .sortedWith(compareBy({ it.lastName.lowercase() }, { it.firstName.lowercase() }))
    }

    val assignedIds = remember(assignments) { assignments.map { it.memberId }.toSet() }
    val unassignedPool = remember(poolMembers, assignedIds) {
        poolMembers.filter { it.id !in assignedIds }
    }

    val selectableForInterest = remember(members, interestedIds, poolSearch) {
        val q = poolSearch.trim().lowercase()
        members.filter { m ->
            m.active && m.testMembership != true && m.id !in interestedIds &&
                (q.isEmpty() || "${m.firstName} ${m.lastName}".lowercase().contains(q))
        }.sortedWith(compareBy({ it.lastName.lowercase() }, { it.firstName.lowercase() }))
    }

    fun persistTeam(teamId: Int, nextAssignments: List<PlanningAssignment>, onDone: () -> Unit = {}) {
        val team = teams.find { it.id == teamId } ?: return
        val draft = drafts[teamId] ?: return
        scope.launch {
            val byId = members.associateBy { it.id }
            runCatching {
                val orderedMembers = TeamPlanningLogic.teamLineupMembers(nextAssignments, teamId, byId)
                val gap = TeamPlanningLogic.lineupGapOk(orderedMembers) { hi, lo ->
                    t("mobile.lineupGapWarn", "QTTR-Abstand >30: $hi über $lo")
                }
                if (gap != null) {
                    Toast.makeText(context, gap, Toast.LENGTH_LONG).show()
                    return@launch
                }
                val items = orderedMembers.mapIndexed { i, m -> TeamLineupAssignmentItem(m.id, i + 1) }
                withContext(Dispatchers.IO) {
                    dependencies.clubTeamsApi.updateClubTeam(
                        teamId,
                        ClubTeamUpdateBody(
                            name = draft.name.trim(),
                            leagueId = team.leagueId,
                            seasonId = team.seasonId ?: seasonId,
                            teamGender = draft.teamGender,
                            teamAgeGroup = draft.teamAgeGroup,
                            plannedLeagueName = draft.plannedLeagueName.trim().ifBlank { null },
                        ),
                    )
                    dependencies.clubTeamsApi.updateLineup(
                        teamId,
                        TeamLineupUpdateBody(assignments = items, lineupHalf = lineupHalf),
                    )
                }
                assignments = TeamPlanningLogic.normalizeAssignments(nextAssignments)
                onTeamsChanged()
                onDone()
            }.onFailure { ex ->
                if (ex !is CancellationException) info = ex.message
            }
        }
    }

    Column(modifier.fillMaxSize()) {
        Text(
            t("teamManagement.planningSubtitle", "Spieler dem Pool „Möchte spielen“ zuordnen und auf Mannschaften verteilen."),
            style = MaterialTheme.typography.caption,
            color = MaterialTheme.colors.onSurface.copy(alpha = 0.78f),
        )
        Spacer(Modifier.height(8.dp))
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) {
            Text(t("common.period", "Halbserie"), style = MaterialTheme.typography.body2)
            listOf("first_half" to "VR", "second_half" to "RR").forEach { (v, label) ->
                OutlinedButton(
                    onClick = { lineupHalf = v },
                    enabled = !loading && lineupHalf != v,
                ) { Text(label) }
            }
            Spacer(Modifier.weight(1f))
            OutlinedButton(onClick = { scope.launch { loadPlanningData() } }, enabled = !loading) {
                Text(t("teamManagement.refreshStats", "Aktualisieren"))
            }
        }

        if (loading) {
            CircularProgressIndicator(Modifier.padding(16.dp))
        } else {
            LazyColumn(
                Modifier
                    .weight(1f)
                    .fillMaxWidth(),
                verticalArrangement = Arrangement.spacedBy(12.dp),
            ) {
                item {
                    Text(t("teamManagement.playersWantToPlay", "Möchte spielen (Pool)"), fontWeight = FontWeight.SemiBold)
                    OutlinedTextField(
                        value = poolSearch,
                        onValueChange = { poolSearch = it },
                        modifier = Modifier.fillMaxWidth(),
                        singleLine = true,
                        label = { Text(t("teamManagement.searchMembers", "Mitglieder suchen")) },
                    )
                    Text(
                        t("mobile.teamPlanningUnassigned", "Noch keiner Mannschaft zugeordnet") + ": ${unassignedPool.size}",
                        style = MaterialTheme.typography.caption,
                    )
                }
                items(unassignedPool, key = { it.id }) { m ->
                    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
                        Column(Modifier.weight(1f)) {
                            Text("${m.firstName} ${m.lastName}", fontWeight = FontWeight.Medium)
                        }
                        if (canWrite) {
                            var addMenu by remember(key1 = m.id) { mutableStateOf(false) }
                            Box {
                                OutlinedButton(onClick = { addMenu = true }) {
                                    Text(t("mobile.teamPlanningAssign", "Zu Mannschaft …"))
                                }
                                DropdownMenu(expanded = addMenu, onDismissRequest = { addMenu = false }) {
                                    teams.forEach { team ->
                                        val draft = drafts[team.id] ?: return@forEach
                                        val pseudo = team.copy(
                                            name = draft.name,
                                            plannedLeagueName = draft.plannedLeagueName.ifBlank { null },
                                            teamGender = draft.teamGender,
                                            teamAgeGroup = draft.teamAgeGroup,
                                        )
                                        val ok = TeamPlanningLogic.isEligible(m, pseudo, seasonLabel)
                                        DropdownMenuItem(
                                            onClick = {
                                                addMenu = false
                                                if (!ok) {
                                                    Toast.makeText(
                                                        context,
                                                        t(
                                                            "mobile.teamPlanningNotEligible",
                                                            "Mitglied passt nicht zu Alters-/Geschlechtsklasse dieser Mannschaft.",
                                                        ),
                                                        Toast.LENGTH_LONG,
                                                    ).show()
                                                    return@DropdownMenuItem
                                                }
                                                val next = TeamPlanningLogic.assignToTeamEnd(assignments, team.id, m.id)
                                                val gapMembers = TeamPlanningLogic.teamLineupMembers(next, team.id, membersById)
                                                val gap = TeamPlanningLogic.lineupGapOk(gapMembers) { hi, lo ->
                                                    t("mobile.lineupGapWarn", "QTTR-Abstand >30: $hi über $lo")
                                                }
                                                if (gap != null) {
                                                    Toast.makeText(context, gap, Toast.LENGTH_LONG).show()
                                                    return@DropdownMenuItem
                                                }
                                                persistTeam(team.id, next)
                                            },
                                            enabled = ok,
                                        ) {
                                            Text(team.name.ifBlank { "#${team.id}" })
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                item {
                    Divider()
                    Text(t("teamManagement.markAsInterested", "Als interessiert markieren"), fontWeight = FontWeight.SemiBold)
                    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        Box(Modifier.weight(1f)) {
                            OutlinedButton(
                                onClick = { addInterestMenu = true },
                                enabled = canWrite && !markingInterest,
                                modifier = Modifier.fillMaxWidth(),
                            ) {
                                Text(
                                    addInterestMemberId?.let { id ->
                                        membersById[id]?.let { "${it.firstName} ${it.lastName}" }
                                    } ?: t("teamManagement.selectMember", "Mitglied wählen"),
                                )
                            }
                            DropdownMenu(expanded = addInterestMenu, onDismissRequest = { addInterestMenu = false }) {
                                selectableForInterest.take(400).forEach { m ->
                                    DropdownMenuItem(
                                        onClick = {
                                            addInterestMemberId = m.id
                                            addInterestMenu = false
                                        },
                                    ) { Text("${m.firstName} ${m.lastName}") }
                                }
                            }
                        }
                        Button(
                            onClick = {
                                val mid = addInterestMemberId ?: return@Button
                                scope.launch {
                                    markingInterest = true
                                    runCatching {
                                        withContext(Dispatchers.IO) {
                                            dependencies.membersApi.setPlayInterest(
                                                clubId,
                                                MemberPlayInterestSetBody(
                                                    memberId = mid,
                                                    seasonId = seasonId,
                                                    lineupHalf = lineupHalf,
                                                    interested = true,
                                                ),
                                            )
                                        }
                                        interestedIds = interestedIds + mid
                                        addInterestMemberId = null
                                    }.onFailure { if (it !is CancellationException) info = it.message }
                                    markingInterest = false
                                }
                            },
                            enabled = canWrite && addInterestMemberId != null && !markingInterest,
                        ) {
                            Text(if (markingInterest) "…" else t("teamManagement.markAsInterested", "Interesse speichern"))
                        }
                    }
                }

                item {
                    Divider()
                    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
                        Text(t("teamManagement.planningTitle", "Planung"), fontWeight = FontWeight.SemiBold)
                        if (canWrite) {
                            Button(
                                onClick = {
                                    scope.launch {
                                        runCatching {
                                            val nextIndex = teams.size + 1
                                            withContext(Dispatchers.IO) {
                                                dependencies.clubTeamsApi.createClubTeam(
                                                    clubId,
                                                    ClubTeamCreateBody(
                                                        name = t("teamManagement.teamName", "Mannschaft") + " $nextIndex",
                                                        leagueId = null,
                                                        seasonId = seasonId,
                                                        teamGender = "open",
                                                        teamAgeGroup = "adult",
                                                        plannedLeagueName = null,
                                                    ),
                                                )
                                            }
                                            onTeamsChanged()
                                        }.onFailure { if (it !is CancellationException) info = it.message }
                                    }
                                },
                            ) {
                                Text(t("teamManagement.addPlanningTeam", "Mannschaft hinzufügen"))
                            }
                        }
                    }
                }

                items(teams, key = { it.id }) { team ->
                    val teamId = team.id
                    val draft = drafts[teamId] ?: return@items
                    CardTeamPlanningBlock(
                        team = team,
                        draft = draft,
                        onDraftChange = { nd -> drafts[teamId] = nd },
                        assignments = assignments,
                        membersById = membersById,
                        canWrite = canWrite,
                        t = t,
                        onPersistLineup = { next -> persistTeam(teamId, next) },
                        onSaveTeamMeta = {
                            val fa = filterAssignmentsForTeamEligibility(
                                teamId,
                                assignments,
                                teams,
                                drafts,
                                membersById,
                                seasonLabel,
                            )
                            persistTeam(teamId, fa)
                        },
                        onMoveInTeam = { memberId, dir ->
                            val next = TeamPlanningLogic.moveWithinTeam(assignments, teamId, memberId, dir)
                            if (next != null) persistTeam(teamId, next)
                        },
                        onRemoveMember = { memberId ->
                            val next = TeamPlanningLogic.removeFromTeam(assignments, teamId, memberId)
                            persistTeam(teamId, next)
                        },
                        onOpenEditor = { onOpenTeamEditor(teamId) },
                        onDeleteRequest = { deleteTeamId = teamId },
                        poolAddCandidates = unassignedPool.filter { u ->
                            val pseudo = team.copy(
                                name = draft.name,
                                plannedLeagueName = draft.plannedLeagueName.ifBlank { null },
                                teamGender = draft.teamGender,
                                teamAgeGroup = draft.teamAgeGroup,
                            )
                            TeamPlanningLogic.isEligible(u, pseudo, seasonLabel)
                        },
                    )
                }
            }
        }
    }

    deleteTeamId?.let { tid ->
        StableAlertDialog(
            onDismissRequest = { deleteTeamId = null },
            title = { Text(t("mobile.teamDeleteTitle", "Mannschaft löschen?")) },
            text = { Text(teams.find { it.id == tid }?.name.orEmpty()) },
            confirmButton = {
                TextButton(
                    onClick = {
                        deleteTeamId = null
                        scope.launch {
                            runCatching {
                                withContext(Dispatchers.IO) { dependencies.clubTeamsApi.deleteClubTeam(tid) }
                                onTeamsChanged()
                            }.onFailure { if (it !is CancellationException) info = it.message }
                        }
                    },
                ) { Text(t("common.delete", "Löschen")) }
            },
            dismissButton = { TextButton(onClick = { deleteTeamId = null }) { Text(t("common.cancel", "Abbrechen")) } },
        )
    }

    info?.let { msg ->
        StableAlertDialog(
            onDismissRequest = { info = null },
            title = { Text(t("common.error", "Fehler")) },
            text = { Text(msg) },
            confirmButton = { TextButton(onClick = { info = null }) { Text(t("common.ok", "OK")) } },
        )
    }
}

@Composable
private fun CardTeamPlanningBlock(
    team: ClubTeamDto,
    draft: TeamDraft,
    onDraftChange: (TeamDraft) -> Unit,
    assignments: List<PlanningAssignment>,
    membersById: Map<Int, Member>,
    canWrite: Boolean,
    t: (String, String) -> String,
    onPersistLineup: (List<PlanningAssignment>) -> Unit,
    onSaveTeamMeta: () -> Unit,
    onMoveInTeam: (Int, Int) -> Unit,
    onRemoveMember: (Int) -> Unit,
    onOpenEditor: () -> Unit,
    onDeleteRequest: () -> Unit,
    poolAddCandidates: List<Member>,
) {
    val teamId = team.id
    val ordered = TeamPlanningLogic.teamLineupMembers(assignments, teamId, membersById)
    var metaMenu by remember { mutableStateOf(false) }
    var addMemberMenu by remember { mutableStateOf(false) }
    val cardContext = LocalContext.current

    Column(Modifier.fillMaxWidth()) {
        Text(team.name.ifBlank { "#$teamId" }, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.subtitle1)
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            OutlinedButton(onClick = onOpenEditor) {
                Text(t("teamManagement.openInWorkspace", "Im Editor öffnen"))
            }
            if (canWrite) {
                OutlinedButton(onClick = onDeleteRequest) {
                    Text(t("common.delete", "Löschen"))
                }
            }
        }
        Spacer(Modifier.height(6.dp))
        OutlinedTextField(
            value = draft.name,
            onValueChange = { onDraftChange(draft.copy(name = it)) },
            label = { Text(t("teamManagement.teamName", "Mannschaft")) },
            modifier = Modifier.fillMaxWidth(),
            enabled = canWrite,
            singleLine = true,
        )
        OutlinedTextField(
            value = draft.plannedLeagueName,
            onValueChange = { onDraftChange(draft.copy(plannedLeagueName = it)) },
            label = { Text(t("teamManagement.plannedLeague", "Geplante Liga")) },
            modifier = Modifier.fillMaxWidth(),
            enabled = canWrite,
            singleLine = true,
        )
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            Box {
                OutlinedButton(onClick = { metaMenu = true }, enabled = canWrite) {
                    Text(t("mobile.teamAgeShort", "AK") + ": ${draft.teamAgeGroup}")
                }
                DropdownMenu(expanded = metaMenu, onDismissRequest = { metaMenu = false }) {
                    listOf("adult", "J19", "J17", "J15", "J13", "J11").forEach { a ->
                        DropdownMenuItem(
                            onClick = {
                                metaMenu = false
                                onDraftChange(draft.copy(teamAgeGroup = a))
                                onSaveTeamMeta()
                            },
                        ) { Text(a) }
                    }
                }
            }
            Box {
                var gMenu by remember { mutableStateOf(false) }
                OutlinedButton(onClick = { gMenu = true }, enabled = canWrite) {
                    Text(t("mobile.teamGenderShort", "GK") + ": ${draft.teamGender}")
                }
                DropdownMenu(expanded = gMenu, onDismissRequest = { gMenu = false }) {
                    listOf("open", "female").forEach { g ->
                        DropdownMenuItem(
                            onClick = {
                                gMenu = false
                                onDraftChange(draft.copy(teamGender = g))
                                onSaveTeamMeta()
                            },
                        ) { Text(g) }
                    }
                }
            }
        }
        if (canWrite) {
            Button(
                onClick = { onSaveTeamMeta() },
                modifier = Modifier.fillMaxWidth(),
            ) {
                Text(t("mobile.teamPlanningSaveTeam", "Mannschaft speichern"))
            }
        }
        Spacer(Modifier.height(4.dp))
        Text(t("teamManagement.selectedLineup", "Meldung"), fontWeight = FontWeight.Medium)
        ordered.forEachIndexed { index, m ->
            Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically) {
                Text("${index + 1}. ${m.firstName} ${m.lastName}")
                if (canWrite) {
                    Row {
                        TextButton(onClick = { onMoveInTeam(m.id, -1) }, enabled = index > 0) { Text("↑") }
                        TextButton(onClick = { onMoveInTeam(m.id, 1) }, enabled = index < ordered.lastIndex) { Text("↓") }
                        TextButton(onClick = { onRemoveMember(m.id) }) { Text("−") }
                    }
                }
            }
        }
        if (canWrite && poolAddCandidates.isNotEmpty()) {
            Box {
                OutlinedButton(onClick = { addMemberMenu = true }) {
                    Text(t("mobile.teamLineupAddToLineup", "Hinzufügen"))
                }
                DropdownMenu(expanded = addMemberMenu, onDismissRequest = { addMemberMenu = false }) {
                    poolAddCandidates.forEach { m ->
                        DropdownMenuItem(
                            onClick = {
                                addMemberMenu = false
                                val next = TeamPlanningLogic.assignToTeamEnd(assignments, teamId, m.id)
                                val gapMembers = TeamPlanningLogic.teamLineupMembers(next, teamId, membersById)
                                val gap = TeamPlanningLogic.lineupGapOk(gapMembers) { hi, lo ->
                                    t("mobile.lineupGapWarn", "QTTR-Abstand >30: $hi über $lo")
                                }
                                if (gap != null) {
                                    Toast.makeText(cardContext, gap, Toast.LENGTH_LONG).show()
                                } else {
                                    onPersistLineup(next)
                                }
                            },
                        ) { Text("${m.firstName} ${m.lastName}") }
                    }
                }
            }
        }
    }
}
