package de.tsschulz.tt_tagebuch.app.ui

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.Card
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
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.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
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.text.font.FontWeight
import androidx.compose.ui.unit.dp
import de.tsschulz.tt_tagebuch.app.AppDependencies
import de.tsschulz.tt_tagebuch.shared.api.ScheduleLogic
import de.tsschulz.tt_tagebuch.shared.api.models.ClubLeagueOptionDto
import de.tsschulz.tt_tagebuch.shared.api.models.ClubTeamDto
import de.tsschulz.tt_tagebuch.shared.api.models.SeasonDto
import de.tsschulz.tt_tagebuch.shared.api.models.canReadTeams
import de.tsschulz.tt_tagebuch.shared.api.models.canWriteTeams
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

private val TeamPad = 20.dp

private enum class TeamWorkspaceSection {
    Teams,
    Planning,
}

@Composable
internal fun TeamManagementScreen(
    dependencies: AppDependencies,
    onBack: () -> Unit,
) {
    val languageCode = LocalLanguageCode.current
    val getMobileString: (String, String) -> String = remember(languageCode) {
        { k: String, fb: String -> MobileStrings.get(languageCode, k, fb) }
    }
    val clubState by dependencies.clubManager.state.collectAsState()
    val clubId = clubState.currentClubId ?: return
    val perms = clubState.currentPermissions
    val canRead = perms?.canReadTeams() == true
    val canWrite = perms?.canWriteTeams() == true
    val scope = rememberCoroutineScope()

    var seasons by remember(clubId) { mutableStateOf<List<SeasonDto>>(emptyList()) }
    var selectedSeasonId by remember(clubId) { mutableStateOf<Int?>(null) }
    var teams by remember(clubId) { mutableStateOf<List<ClubTeamDto>>(emptyList()) }
    var leagues by remember(clubId) { mutableStateOf<List<ClubLeagueOptionDto>>(emptyList()) }
    var loading by remember(clubId) { mutableStateOf(true) }
    var error by remember(clubId) { mutableStateOf<String?>(null) }
    var search by remember(clubId) { mutableStateOf("") }
    var loadTick by remember(clubId) { mutableStateOf(0) }

    var editorOpen by remember { mutableStateOf(false) }
    var editorTeamId by remember { mutableStateOf<Int?>(null) }

    var workspace by remember { mutableStateOf(TeamWorkspaceSection.Teams) }

    var seasonMenu by remember { mutableStateOf(false) }

    var deleteTarget by remember { mutableStateOf<ClubTeamDto?>(null) }
    var infoMessage by remember { mutableStateOf<String?>(null) }

    fun openEditor(team: ClubTeamDto) {
        editorTeamId = team.id
        editorOpen = true
    }

    fun openNewTeamEditor() {
        editorTeamId = null
        editorOpen = true
    }

    // Saisons + Default-Saison ohne selectedSeasonId in denselben Keys wie den Team-Load zu mischen:
    // Sonst setzt der Effekt selectedSeasonId, wird abgebrochen, runCatching zeigt die Cancellation-Meldung.
    LaunchedEffect(clubId) {
        try {
            val allSeasons = withContext(Dispatchers.IO) { dependencies.seasonsApi.listSeasons() }
                .sortedByDescending { it.id }
            seasons = allSeasons
            if (allSeasons.isEmpty()) {
                selectedSeasonId = null
                teams = emptyList()
                leagues = emptyList()
                loading = false
                return@LaunchedEffect
            }
            if (selectedSeasonId == null) {
                selectedSeasonId = withContext(Dispatchers.IO) { dependencies.seasonsApi.getCurrentSeason() }.id
            }
        } catch (e: CancellationException) {
            throw e
        } catch (e: Throwable) {
            error = e.message ?: getMobileString("mobile.teamLoadError", "Daten konnten nicht geladen werden.")
        }
    }

    LaunchedEffect(clubId, selectedSeasonId, loadTick) {
        val sid = selectedSeasonId ?: return@LaunchedEffect
        loading = true
        error = null
        try {
            val t = withContext(Dispatchers.IO) { dependencies.clubTeamsApi.listClubTeams(clubId, sid) }
            val lg = withContext(Dispatchers.IO) { dependencies.clubTeamsApi.listLeagues(clubId, sid) }
            teams = ScheduleLogic.sortClubTeams(t)
            leagues = lg.sortedBy { it.name.lowercase() }
        } catch (e: CancellationException) {
            throw e
        } catch (e: Throwable) {
            error = e.message ?: getMobileString("mobile.teamLoadError", "Daten konnten nicht geladen werden.")
        } finally {
            loading = false
        }
    }

    val filtered = remember(teams, search) {
        val q = search.trim().lowercase()
        if (q.isEmpty()) teams
        else teams.filter { t ->
            listOf(t.name, t.league?.name, t.season?.season, t.plannedLeagueName)
                .filterNotNull()
                .any { it.lowercase().contains(q) }
        }
    }

    Box(Modifier.fillMaxSize()) {
        val editorSeasonId = selectedSeasonId
        if (editorOpen && editorSeasonId != null) {
            TeamEditorScreen(
                dependencies = dependencies,
                clubId = clubId,
                seasonId = editorSeasonId,
                seasonLabel = seasons.find { it.id == editorSeasonId }?.season.orEmpty(),
                initialTeamId = editorTeamId,
                onBack = { editorOpen = false },
                onSaved = { loadTick++ },
            )
        } else {
            Column(Modifier.fillMaxSize().padding(TeamPad)) {
        Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
            IconButton(onClick = onBack) {
                Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null)
            }
            Text(
                getMobileString("navigation.teamManagement", "Team-Verwaltung"),
                style = MaterialTheme.typography.h6,
                fontWeight = FontWeight.SemiBold,
                modifier = Modifier.weight(1f),
            )
            if (canWrite && workspace == TeamWorkspaceSection.Teams) {
                Button(
                    onClick = { openNewTeamEditor() },
                    enabled = !loading && selectedSeasonId != null,
                ) {
                    Text(getMobileString("mobile.teamNew", "Neue Mannschaft"))
                }
            }
        }

        if (!canRead) {
            Text(getMobileString("mobile.noTeamAccess", "Keine Berechtigung für die Team-Verwaltung."))
            return@Column
        }

        if (workspace == TeamWorkspaceSection.Teams) {
            Text(
                getMobileString("mobile.teamsIntro", "Mannschaften pro Saison verwalten (Name, Liga, geplante Liga, Geschlechtsklasse, Altersklasse)."),
                style = MaterialTheme.typography.caption,
                color = MaterialTheme.colors.onSurface.copy(alpha = 0.72f),
            )
        } else {
            Text(
                getMobileString("teamManagement.planningSubtitle", "Spieler dem Pool „Möchte spielen“ zuordnen und auf Mannschaften verteilen."),
                style = MaterialTheme.typography.caption,
                color = MaterialTheme.colors.onSurface.copy(alpha = 0.72f),
            )
        }
        Spacer(Modifier.height(8.dp))

        Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            Text(getMobileString("mobile.season", "Saison") + ":", style = MaterialTheme.typography.body2)
            Box {
                OutlinedButton(onClick = { seasonMenu = true }, enabled = seasons.isNotEmpty()) {
                    Text(
                        seasons.find { it.id == selectedSeasonId }?.season
                            ?: getMobileString("mobile.seasonPick", "Saison wählen"),
                    )
                }
                DropdownMenu(expanded = seasonMenu, onDismissRequest = { seasonMenu = false }) {
                    seasons.forEach { s ->
                        DropdownMenuItem(
                            onClick = {
                                selectedSeasonId = s.id
                                seasonMenu = false
                            },
                        ) { Text(s.season) }
                    }
                }
            }
        }

        Spacer(Modifier.height(8.dp))
        Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            if (workspace == TeamWorkspaceSection.Teams) {
                Button(onClick = { }, enabled = false, modifier = Modifier.weight(1f)) {
                    Text(getMobileString("mobile.teamWorkspaceTeams", "Mannschaften"))
                }
            } else {
                OutlinedButton(onClick = { workspace = TeamWorkspaceSection.Teams }, modifier = Modifier.weight(1f)) {
                    Text(getMobileString("mobile.teamWorkspaceTeams", "Mannschaften"))
                }
            }
            if (workspace == TeamWorkspaceSection.Planning) {
                Button(onClick = { }, enabled = false, modifier = Modifier.weight(1f)) {
                    Text(getMobileString("mobile.teamWorkspacePlanning", "Planung"))
                }
            } else {
                OutlinedButton(
                    onClick = { workspace = TeamWorkspaceSection.Planning },
                    enabled = selectedSeasonId != null,
                    modifier = Modifier.weight(1f),
                ) {
                    Text(getMobileString("mobile.teamWorkspacePlanning", "Planung"))
                }
            }
        }

        Spacer(Modifier.height(8.dp))

        when (workspace) {
            TeamWorkspaceSection.Teams -> {
                OutlinedTextField(
                    value = search,
                    onValueChange = { search = it },
                    modifier = Modifier.fillMaxWidth(),
                    singleLine = true,
                    label = { Text(getMobileString("mobile.teamSearch", "Mannschaft suchen")) },
                )

                error?.let {
                    Spacer(Modifier.height(8.dp))
                    Text(it, color = MaterialTheme.colors.error)
                }

                if (loading && teams.isEmpty()) {
                    Box(Modifier.fillMaxWidth().padding(top = 24.dp), contentAlignment = Alignment.Center) {
                        CircularProgressIndicator()
                    }
                    return@Column
                }

                if (!loading && teams.isEmpty()) {
                    Spacer(Modifier.height(16.dp))
                    Text(getMobileString("mobile.noTeams", "Keine Mannschaften für diese Saison."))
                    return@Column
                }

                LazyColumn(
                    modifier = Modifier
                        .weight(1f)
                        .fillMaxWidth(),
                    verticalArrangement = Arrangement.spacedBy(8.dp),
                ) {
                    items(filtered, key = { it.id }) { team ->
                        Card(elevation = 1.dp, modifier = Modifier.fillMaxWidth()) {
                            Column(Modifier.padding(12.dp)) {
                                Text(team.name.ifBlank { "#${team.id}" }, fontWeight = FontWeight.SemiBold)
                                val lg = team.league?.name?.takeIf { it.isNotBlank() }
                                    ?: getMobileString("mobile.noLeague", "Keine Liga")
                                Text(lg, style = MaterialTheme.typography.caption)
                                team.season?.season?.takeIf { it.isNotBlank() }?.let {
                                    Text(it, style = MaterialTheme.typography.caption)
                                }
                                team.plannedLeagueName?.takeIf { it.isNotBlank() }?.let { pl ->
                                    Text(
                                        getMobileString("mobile.plannedLeagueShort", "Geplant: ") + pl,
                                        style = MaterialTheme.typography.caption,
                                    )
                                }
                                val g = team.teamGender ?: "open"
                                val a = team.teamAgeGroup ?: "adult"
                                val genShort = getMobileString("mobile.teamGenderShort", "Geschlecht")
                                val ageShort = getMobileString("mobile.teamAgeShort", "AK")
                                Text(
                                    "$genShort: ${labelGender(getMobileString, g)} · $ageShort: ${labelAge(getMobileString, a)}",
                                    style = MaterialTheme.typography.caption,
                                )
                                team.myTischtennisTeamId?.takeIf { it.isNotBlank() }?.let { mid ->
                                    Text("myTischtennis: $mid", style = MaterialTheme.typography.caption)
                                }
                                if (canWrite) {
                                    Row(Modifier.padding(top = 8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                                        TextButton(onClick = { openEditor(team) }) {
                                            Text(getMobileString("common.edit", "Bearbeiten"))
                                        }
                                        TextButton(onClick = { deleteTarget = team }) {
                                            Text(getMobileString("common.delete", "Löschen"), color = MaterialTheme.colors.error)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            TeamWorkspaceSection.Planning -> {
                val sid = selectedSeasonId
                if (sid == null) {
                    Text(getMobileString("mobile.seasonPick", "Saison wählen"))
                } else {
                    TeamPlanningScreen(
                        dependencies = dependencies,
                        clubId = clubId,
                        seasonId = sid,
                        seasonLabel = seasons.find { it.id == sid }?.season.orEmpty(),
                        teams = teams,
                        canWrite = canWrite,
                        onTeamsChanged = { loadTick++ },
                        onOpenTeamEditor = { tid ->
                            editorTeamId = tid
                            editorOpen = true
                        },
                        t = getMobileString,
                        modifier = Modifier.weight(1f).fillMaxWidth(),
                    )
                }
            }
        }
            }
        }

        deleteTarget?.let { target ->
            StableAlertDialog(
                onDismissRequest = { deleteTarget = null },
                title = { Text(getMobileString("mobile.teamDeleteTitle", "Mannschaft löschen?")) },
                text = { Text(target.name.ifBlank { "#${target.id}" }) },
                confirmButton = {
                    TextButton(
                        onClick = {
                            val id = target.id
                            deleteTarget = null
                            scope.launch {
                                runCatching {
                                    withContext(Dispatchers.IO) { dependencies.clubTeamsApi.deleteClubTeam(id) }
                                    withContext(Dispatchers.IO) {
                                        dependencies.scheduleManager.loadClubTeams(clubId)
                                    }
                                    loadTick++
                                }.onFailure { ex ->
                                    if (ex is CancellationException) throw ex
                                    infoMessage = ex.message
                                }
                            }
                        },
                    ) { Text(getMobileString("common.delete", "Löschen")) }
                },
                dismissButton = {
                    TextButton(onClick = { deleteTarget = null }) {
                        Text(getMobileString("common.cancel", "Abbrechen"))
                    }
                },
            )
        }

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

private fun labelGender(t: (String, String) -> String, code: String): String =
    when (code) {
        "male" -> t("mobile.teamGenderMale", "Männlich")
        "female" -> t("mobile.teamGenderFemale", "Weiblich")
        else -> t("mobile.teamGenderOpen", "Offen")
    }

private fun labelAge(t: (String, String) -> String, code: String): String =
    if (code == "adult") t("mobile.teamAgeAdult", "Erwachsene") else code
