package de.tsschulz.tt_tagebuch.app.ui

import androidx.compose.foundation.horizontalScroll
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.heightIn
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Card
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Divider
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
import androidx.compose.material.TextButton
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.saveable.rememberSaveable
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 androidx.compose.ui.unit.dp
import de.tsschulz.tt_tagebuch.app.AppDependencies
import de.tsschulz.tt_tagebuch.app.pdf.shareFileWithMime
import de.tsschulz.tt_tagebuch.app.stats.TrainingStatsDerived
import de.tsschulz.tt_tagebuch.shared.api.models.TrainingStatsMember
import de.tsschulz.tt_tagebuch.shared.i18n.MobileStrings
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File

private val StatsPad = 20.dp
private val StatsTouchMin = 48.dp

private val weekdayFilterLabels = listOf(
    "Sonntag" to "0",
    "Montag" to "1",
    "Dienstag" to "2",
    "Mittwoch" to "3",
    "Donnerstag" to "4",
    "Freitag" to "5",
    "Samstag" to "6",
)

/** Bits für einklappbare Statistik-Bereiche (Start: alle zu). */
private const val EXP_OVERVIEW = 0
private const val EXP_MONTHLY = 1
private const val EXP_WEEKDAY = 2
private const val EXP_STRUCTURE = 3
private const val EXP_BEST_DAY = 4
private const val EXP_GROUPS = 5
private const val EXP_AGE = 6
private const val EXP_RAW = 7
private const val EXP_TRAINING_DAYS = 8
private const val EXP_MEMBERS = 9

private fun statsPanelExpanded(mask: Int, bit: Int): Boolean = (mask shr bit) and 1 == 1

private fun statsPanelToggle(mask: Int, bit: Int): Int = mask xor (1 shl bit)

@Composable
internal fun TrainingStatsScreen(dependencies: AppDependencies) {
    val clubState by dependencies.clubManager.state.collectAsState()
    val statsState by dependencies.trainingStatsManager.state.collectAsState()
    val clubId = clubState.currentClubId ?: return
    val context = LocalContext.current
    val scope = rememberCoroutineScope()

    var selectedWeekday by rememberSaveable { mutableStateOf("all") }
    var selectedTrainingDay by rememberSaveable { mutableStateOf("all") }
    var selectedTrainingGroup by rememberSaveable { mutableStateOf("all") }
    var expandedPanelsMask by rememberSaveable { mutableStateOf(0) }
    var sortField by rememberSaveable { mutableStateOf("name") }
    var sortAsc by rememberSaveable { mutableStateOf(true) }

    var weekdayMenu by remember { mutableStateOf(false) }
    var trainingDayMenu by remember { mutableStateOf(false) }
    var trainingGroupMenu by remember { mutableStateOf(false) }

    var detailMember by remember { mutableStateOf<TrainingStatsMember?>(null) }

    LaunchedEffect(clubId) {
        selectedWeekday = "all"
        selectedTrainingDay = "all"
        selectedTrainingGroup = "all"
        dependencies.trainingStatsManager.loadStats(clubId)
    }

    val languageCode = LocalLanguageCode.current
    fun statsTr(key: String, fallback: String) = MobileStrings.get(languageCode, key, fallback)

    fun onSortColumn(field: String) {
        if (sortField == field) {
            sortAsc = !sortAsc
        } else {
            sortField = field
            sortAsc = false
        }
    }

    fun sortIcon(field: String): String = when {
        sortField != field -> "↕"
        sortAsc -> "↑"
        else -> "↓"
    }

    val stats = statsState.stats
    val trainingDaysByWeekday = remember(stats, selectedWeekday) {
        if (stats == null) emptyList() else TrainingStatsDerived.trainingDaysByWeekday(stats.trainingDays, selectedWeekday)
    }

    LaunchedEffect(selectedWeekday, trainingDaysByWeekday) {
        if (selectedTrainingDay != "all" && trainingDaysByWeekday.none { it.id.toString() == selectedTrainingDay }) {
            selectedTrainingDay = "all"
        }
    }

    val trainingDayOptions = remember(trainingDaysByWeekday) {
        trainingDaysByWeekday.map { day ->
            day.id.toString() to "${TrainingStatsDerived.formatDateGerman(day.date)} (${TrainingStatsDerived.weekdayGerman(day.date)})"
        }
    }

    val trainingGroupOptions = remember(stats) {
        if (stats == null) emptyList() else TrainingStatsDerived.trainingGroupOptions(stats.members)
    }

    val participantIds = remember(stats, selectedTrainingDay) {
        if (stats == null) null else TrainingStatsDerived.trainingDayParticipantIds(stats.trainingDays, selectedTrainingDay)
    }

    val filteredMembers = remember(stats, selectedTrainingGroup, participantIds) {
        if (stats == null) emptyList() else TrainingStatsDerived.filteredMembers(stats.members, selectedTrainingGroup, participantIds)
    }

    val filteredTrainingDays = remember(trainingDaysByWeekday, selectedTrainingDay) {
        TrainingStatsDerived.filteredTrainingDays(trainingDaysByWeekday, selectedTrainingDay)
    }

    val filteredOverview = remember(filteredTrainingDays, filteredMembers) {
        TrainingStatsDerived.filteredOverview(filteredTrainingDays, filteredMembers)
    }

    val filteredMonthlyTrend = remember(filteredTrainingDays) {
        TrainingStatsDerived.filteredMonthlyTrend(filteredTrainingDays)
    }

    val filteredWeekdayStats = remember(filteredTrainingDays) {
        TrainingStatsDerived.filteredWeekdayStats(filteredTrainingDays)
    }

    val filteredMemberDistribution = remember(filteredMembers) {
        TrainingStatsDerived.filteredMemberDistribution(filteredMembers)
    }

    val groupPerformance = remember(filteredMembers) {
        TrainingStatsDerived.groupPerformance(filteredMembers)
    }

    val ageGroupStats = remember(filteredMembers) {
        TrainingStatsDerived.ageGroupStats(filteredMembers)
    }

    val sortedMembers = remember(filteredMembers, sortField, sortAsc) {
        TrainingStatsDerived.sortedMembers(filteredMembers, sortField, sortAsc)
    }

    val maxMonthAvg = remember(filteredMonthlyTrend) {
        (filteredMonthlyTrend.maxOfOrNull { it.averageParticipants } ?: 1.0).coerceAtLeast(1.0)
    }

    val scroll = rememberScrollState()

    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(scroll)
            .imePadding()
            .navigationBarsPadding()
            .padding(horizontal = StatsPad, vertical = 16.dp),
    ) {
        TrainingStatsMainHeader(statsTr("trainingStats.title", "Trainings-Statistik"))
        OutlinedButton(
            onClick = { dependencies.applicationScope.launch { dependencies.trainingStatsManager.loadStats(clubId) } },
            modifier = Modifier
                .fillMaxWidth()
                .heightIn(min = StatsTouchMin),
        ) {
            Text(statsTr("mobile.refresh", "Aktualisieren"))
        }
        if (statsState.isLoading) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 8.dp),
                horizontalArrangement = Arrangement.Center,
            ) {
                CircularProgressIndicator()
            }
        }
        if (!statsState.error.isNullOrBlank()) {
            Text(statsState.error!!, color = MaterialTheme.colors.error, modifier = Modifier.padding(vertical = 8.dp))
        }

        stats?.let { s ->
            StatsSectionTitle(statsTr("mobile.filters", "Filter"))
            Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                Box(modifier = Modifier.weight(1f)) {
                    OutlinedButton(
                        onClick = { weekdayMenu = true },
                        modifier = Modifier.fillMaxWidth().heightIn(min = StatsTouchMin),
                    ) {
                        val label = if (selectedWeekday == "all") {
                            statsTr("trainingStats.allWeekdays", "Alle Wochentage")
                        } else {
                            weekdayFilterLabels.find { it.second == selectedWeekday }?.first ?: selectedWeekday
                        }
                        Text(label, maxLines = 1)
                    }
                    DropdownMenu(expanded = weekdayMenu, onDismissRequest = { weekdayMenu = false }) {
                        DropdownMenuItem(onClick = {
                            selectedWeekday = "all"
                            weekdayMenu = false
                        }) { Text(statsTr("trainingStats.allWeekdays", "Alle Wochentage")) }
                        weekdayFilterLabels.forEach { (label, value) ->
                            DropdownMenuItem(onClick = {
                                selectedWeekday = value
                                weekdayMenu = false
                            }) { Text(label) }
                        }
                    }
                }
                Box(modifier = Modifier.weight(1f)) {
                    OutlinedButton(
                        onClick = { trainingDayMenu = true },
                        modifier = Modifier.fillMaxWidth().heightIn(min = StatsTouchMin),
                    ) {
                        val label = trainingDayOptions.find { it.first == selectedTrainingDay }?.second
                            ?: statsTr("trainingStats.allTrainingDays", "Alle Trainingstage")
                        Text(label, maxLines = 2)
                    }
                    DropdownMenu(expanded = trainingDayMenu, onDismissRequest = { trainingDayMenu = false }) {
                        DropdownMenuItem(onClick = {
                            selectedTrainingDay = "all"
                            trainingDayMenu = false
                        }) { Text(statsTr("trainingStats.allTrainingDays", "Alle Trainingstage")) }
                        trainingDayOptions.forEach { (id, label) ->
                            DropdownMenuItem(onClick = {
                                selectedTrainingDay = id
                                trainingDayMenu = false
                            }) { Text(label) }
                        }
                    }
                }
            }
            Box(modifier = Modifier.fillMaxWidth().padding(top = 8.dp)) {
                OutlinedButton(
                    onClick = { trainingGroupMenu = true },
                    modifier = Modifier.fillMaxWidth().heightIn(min = StatsTouchMin),
                ) {
                    val label = if (selectedTrainingGroup == "all") {
                        statsTr("trainingStats.allGroups", "Alle Trainingsgruppen")
                    } else {
                        trainingGroupOptions.find { it.first == selectedTrainingGroup }?.second ?: selectedTrainingGroup
                    }
                    Text(label, maxLines = 1)
                }
                DropdownMenu(expanded = trainingGroupMenu, onDismissRequest = { trainingGroupMenu = false }) {
                    DropdownMenuItem(onClick = {
                        selectedTrainingGroup = "all"
                        trainingGroupMenu = false
                    }) { Text(statsTr("trainingStats.allGroups", "Alle Trainingsgruppen")) }
                    trainingGroupOptions.forEach { (id, name) ->
                        DropdownMenuItem(onClick = {
                            selectedTrainingGroup = id
                            trainingGroupMenu = false
                        }) { Text(name) }
                    }
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.panelSummary", "Kennzahlen (Filter)"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_OVERVIEW),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_OVERVIEW) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_OVERVIEW)) {
                Row(modifier = Modifier.fillMaxWidth()) {
                    StatMiniCard(
                        title = statsTr("members.activeMembers", "Aktive Mitglieder"),
                        value = filteredMembers.size.toString(),
                        modifier = Modifier.weight(1f),
                    )
                    StatMiniCard(
                        title = statsTr("trainingStats.trainingDays12m", "Trainingstage (Filter)"),
                        value = filteredTrainingDays.size.toString(),
                        modifier = Modifier.weight(1f),
                    )
                }
                Row(modifier = Modifier.fillMaxWidth()) {
                    StatMiniCard(
                        title = statsTr("trainingStats.averageParticipants", "Ø Teilnehmer je Training"),
                        value = "%.1f".format(filteredOverview.averageParticipants),
                        modifier = Modifier.weight(1f),
                    )
                    StatMiniCard(
                        title = statsTr("trainingStats.totalParticipations", "Teilnahmen gesamt"),
                        value = filteredOverview.totalParticipants.toString(),
                        modifier = Modifier.weight(1f),
                    )
                }
                Row(modifier = Modifier.fillMaxWidth()) {
                    StatMiniCard(
                        title = statsTr("trainingStats.attendanceRate12m", "Anwesenheitsquote %"),
                        value = "%.1f %%".format(filteredOverview.attendanceRate),
                        modifier = Modifier.weight(1f),
                    )
                    StatMiniCard(
                        title = statsTr("trainingStats.notInTraining", "Nicht im Training"),
                        value = filteredMembers.count { it.notInTraining }.toString(),
                        modifier = Modifier.weight(1f),
                    )
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.panelMonthlyTrend", "Monatlicher Verlauf"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_MONTHLY),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_MONTHLY) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_MONTHLY)) {
                Text(
                    "${filteredMonthlyTrend.size} Monate",
                    style = MaterialTheme.typography.caption,
                    modifier = Modifier.padding(bottom = 4.dp),
                )
                filteredMonthlyTrend.forEach { month ->
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(vertical = 6.dp),
                        verticalAlignment = Alignment.CenterVertically,
                    ) {
                        Column(modifier = Modifier.weight(1f)) {
                            Text(month.label, fontWeight = FontWeight.SemiBold)
                            Text(
                                "${month.trainingCount} ${statsTr("trainingStats.trainingDaysShort", "Trainingstage")}",
                                style = MaterialTheme.typography.caption,
                            )
                        }
                        Column(modifier = Modifier.widthIn(min = 96.dp), horizontalAlignment = Alignment.End) {
                            Text("%.1f".format(month.averageParticipants), fontWeight = FontWeight.Medium)
                        }
                    }
                    LinearProgressIndicator(
                        progress = (month.averageParticipants / maxMonthAvg).toFloat().coerceIn(0f, 1f),
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(6.dp),
                    )
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.panelWeekdayStats", "Trainingstage nach Wochentag"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_WEEKDAY),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_WEEKDAY) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_WEEKDAY)) {
                Text(
                    "${filteredWeekdayStats.size} ${statsTr("trainingStats.weekdays", "Wochentage")}",
                    style = MaterialTheme.typography.caption,
                    modifier = Modifier.padding(bottom = 4.dp),
                )
                filteredWeekdayStats.chunked(2).forEach { row ->
                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        row.forEach { w ->
                            StatMiniCard(
                                title = w.weekday,
                                value = "${w.trainingCount} Term.\nØ %.1f".format(w.averageParticipants),
                                modifier = Modifier.weight(1f),
                            )
                        }
                        if (row.size == 1) Spacer(modifier = Modifier.weight(1f))
                    }
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.panelMemberStructure", "Mitgliederstruktur"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_STRUCTURE),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_STRUCTURE) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_STRUCTURE)) {
                Row(modifier = Modifier.fillMaxWidth()) {
                    StatMiniCard(
                        title = statsTr("trainingStats.distHighlyActive", "Sehr aktiv"),
                        value = filteredMemberDistribution.highlyActive.toString(),
                        modifier = Modifier.weight(1f),
                    )
                    StatMiniCard(
                        title = statsTr("trainingStats.distRegular", "Regelmäßig"),
                        value = filteredMemberDistribution.regular.toString(),
                        modifier = Modifier.weight(1f),
                    )
                }
                Row(modifier = Modifier.fillMaxWidth()) {
                    StatMiniCard(
                        title = statsTr("trainingStats.distOccasional", "Gelegentlich"),
                        value = filteredMemberDistribution.occasional.toString(),
                        modifier = Modifier.weight(1f),
                    )
                    StatMiniCard(
                        title = statsTr("trainingStats.distInactive", "Ohne Teilnahme"),
                        value = filteredMemberDistribution.inactive.toString(),
                        modifier = Modifier.weight(1f),
                    )
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.panelBestDay", "Stärkster Trainingstag"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_BEST_DAY),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_BEST_DAY) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_BEST_DAY)) {
                val best = filteredOverview.bestTrainingDay
                Card(modifier = Modifier.fillMaxWidth(), elevation = 2.dp) {
                    Column(modifier = Modifier.padding(12.dp)) {
                        if (best != null) {
                            Text(TrainingStatsDerived.formatDateGerman(best.date), fontWeight = FontWeight.Bold)
                            Text(TrainingStatsDerived.weekdayGerman(best.date), style = MaterialTheme.typography.body2)
                            Text(
                                "${best.participantCount} ${statsTr("trainingStats.participants", "Teilnehmer")}",
                                style = MaterialTheme.typography.h6,
                                modifier = Modifier.padding(top = 4.dp),
                            )
                            Text(
                                statsTr("trainingStats.bestDayHint", "Beim bestbesuchten Training im Filterzeitraum."),
                                style = MaterialTheme.typography.caption,
                            )
                        } else {
                            Text(statsTr("trainingStats.noData", "Keine Daten"))
                        }
                    }
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.panelGroupPerformance", "Entwicklung pro Gruppe"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_GROUPS),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_GROUPS) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_GROUPS)) {
                Text(
                    "${groupPerformance.size} ${statsTr("trainingStats.groups", "Gruppen")}",
                    style = MaterialTheme.typography.caption,
                )
                groupPerformance.forEach { g ->
                    Card(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(vertical = 4.dp),
                        elevation = 1.dp,
                    ) {
                        Column(modifier = Modifier.padding(10.dp)) {
                            Text(g.name, fontWeight = FontWeight.SemiBold)
                            Text("${g.memberCount} ${statsTr("members.members", "Mitglieder")}", style = MaterialTheme.typography.caption)
                            Text(
                                "%.1f Ø / 12M · %.1f %% ${statsTr("trainingStats.presence", "Anwesenheit")}"
                                    .format(g.averageParticipations12Months, g.participationRate),
                                style = MaterialTheme.typography.body2,
                                modifier = Modifier.padding(top = 4.dp),
                            )
                        }
                    }
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.panelAgeGroups", "Anwesenheit nach Altersklasse"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_AGE),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_AGE) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_AGE)) {
                ageGroupStats.chunked(2).forEach { row ->
                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                        row.forEach { a ->
                            StatMiniCard(
                                title = a.label,
                                value = "${a.memberCount}\nØ %.1f / 12M".format(a.averageParticipations12Months),
                                modifier = Modifier.weight(1f),
                            )
                        }
                        if (row.size == 1) Spacer(modifier = Modifier.weight(1f))
                    }
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.rawCounts", "Rohzahlen (Verein)"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_RAW),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_RAW) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_RAW)) {
                StatsDetailLine(statsTr("trainingStats.trainings12Months", "Trainings 12 Monate"), s.trainingsCount12Months.toString())
                StatsDetailLine(statsTr("trainingStats.trainings3Months", "Trainings 3 Monate"), s.trainingsCount3Months.toString())
                StatsDetailLine(statsTr("members.activeMembers", "Aktive Mitglieder (Backend)"), s.overview.activeMembersCount.toString())
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.trainingDays", "Trainingstage"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_TRAINING_DAYS),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_TRAINING_DAYS) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_TRAINING_DAYS)) {
                filteredTrainingDays.forEach { day ->
                    Card(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(vertical = 4.dp),
                        elevation = 1.dp,
                    ) {
                        Column(modifier = Modifier.padding(10.dp)) {
                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween,
                            ) {
                                Text(TrainingStatsDerived.formatDateGerman(day.date), fontWeight = FontWeight.SemiBold)
                                Text("${day.participantCount} ${statsTr("trainingStats.participants", "Teilnehmer")}")
                            }
                            Text(TrainingStatsDerived.weekdayGerman(day.date), style = MaterialTheme.typography.caption)
                            if (day.participants.isNotEmpty()) {
                                Text(
                                    day.participants.joinToString(", ") { p -> "${p.firstName} ${p.lastName}".trim() },
                                    style = MaterialTheme.typography.body2,
                                    modifier = Modifier.padding(top = 6.dp),
                                )
                            } else {
                                Text(
                                    statsTr("trainingStats.noParticipants", "Keine Teilnehmer"),
                                    style = MaterialTheme.typography.caption,
                                    modifier = Modifier.padding(top = 6.dp),
                                )
                            }
                        }
                    }
                }
            }

            CollapsibleHeader(
                title = statsTr("trainingStats.memberParticipations", "Mitglieder-Teilnahmen"),
                expanded = statsPanelExpanded(expandedPanelsMask, EXP_MEMBERS),
                onToggle = { expandedPanelsMask = statsPanelToggle(expandedPanelsMask, EXP_MEMBERS) },
            )
            if (statsPanelExpanded(expandedPanelsMask, EXP_MEMBERS)) {
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(8.dp),
                ) {
                    OutlinedButton(
                        onClick = {
                            scope.launch(Dispatchers.IO) {
                                val csv = TrainingStatsDerived.buildMembersCsv(sortedMembers)
                                val f = File(context.cacheDir, "training-stats-${System.currentTimeMillis()}.csv")
                                f.writeText(csv, Charsets.UTF_8)
                                withContext(Dispatchers.Main) {
                                    shareFileWithMime(
                                        context,
                                        f,
                                        "text/csv",
                                        statsTr("trainingStats.shareCsv", "Mitgliederstatistik teilen"),
                                    )
                                }
                            }
                        },
                        modifier = Modifier
                            .weight(1f)
                            .heightIn(min = StatsTouchMin),
                    ) {
                        Text(statsTr("trainingStats.exportCsv", "CSV exportieren"))
                    }
                }
                val hScroll = rememberScrollState()
                Row(Modifier.horizontalScroll(hScroll)) {
                    Column(modifier = Modifier.widthIn(min = 920.dp)) {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            verticalAlignment = Alignment.CenterVertically,
                        ) {
                            SortHeader(statsTr("trainingStats.name", "Name"), "name", ::sortIcon, ::onSortColumn, 140.dp)
                            Text("TTR", modifier = Modifier.widthIn(min = 48.dp), fontWeight = FontWeight.SemiBold, style = MaterialTheme.typography.caption)
                            Text("QTTR", modifier = Modifier.widthIn(min = 52.dp), fontWeight = FontWeight.SemiBold, style = MaterialTheme.typography.caption)
                            Text(
                                statsTr("trainingStats.birthdate", "Geb."),
                                modifier = Modifier.widthIn(min = 88.dp),
                                fontWeight = FontWeight.SemiBold,
                                style = MaterialTheme.typography.caption,
                            )
                            SortHeader("12M", "participation12Months", ::sortIcon, ::onSortColumn, 44.dp)
                            SortHeader("3M", "participation3Months", ::sortIcon, ::onSortColumn, 44.dp)
                            SortHeader(statsTr("trainingStats.totalShort", "Σ"), "participationTotal", ::sortIcon, ::onSortColumn, 44.dp)
                            SortHeader(statsTr("trainingStats.lastShort", "Letzt."), "lastTrainingTs", ::sortIcon, ::onSortColumn, 88.dp)
                            Text(statsTr("trainingStats.actions", "Aktion"), modifier = Modifier.widthIn(min = 88.dp), fontWeight = FontWeight.SemiBold)
                        }
                        Divider()
                        sortedMembers.forEach { m ->
                            Row(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .padding(vertical = 6.dp),
                                verticalAlignment = Alignment.CenterVertically,
                            ) {
                                Text(
                                    "${m.firstName} ${m.lastName}".trim().ifBlank { "—" },
                                    modifier = Modifier.widthIn(min = 140.dp, max = 180.dp),
                                    maxLines = 2,
                                    style = MaterialTheme.typography.body2,
                                )
                                Text((m.ttr ?: "–").toString(), modifier = Modifier.widthIn(48.dp))
                                Text((m.qttr ?: "–").toString(), modifier = Modifier.widthIn(52.dp))
                                Text(
                                    TrainingStatsDerived.formatDateGerman(m.birthDate).takeUnless { it == "-" } ?: "–",
                                    modifier = Modifier.widthIn(88.dp),
                                    style = MaterialTheme.typography.caption,
                                )
                                Text(m.participation12Months.toString(), modifier = Modifier.widthIn(44.dp))
                                Text(m.participation3Months.toString(), modifier = Modifier.widthIn(44.dp))
                                Text(m.participationTotal.toString(), modifier = Modifier.widthIn(44.dp))
                                Text(
                                    TrainingStatsDerived.formatDateGerman(m.lastTraining).takeUnless { it == "-" } ?: "–",
                                    modifier = Modifier.widthIn(88.dp),
                                    style = MaterialTheme.typography.caption,
                                )
                                TextButton(onClick = { detailMember = m }) {
                                    Text(statsTr("trainingStats.showDetails", "Details"))
                                }
                            }
                            Divider()
                        }
                    }
                }
            }
        }
    }

    detailMember?.let { member ->
        StableAlertDialog(
            onDismissRequest = { detailMember = null },
            title = {
                Text(
                    "${statsTr("trainingDetails.title", "Trainingsdetails")}: ${member.firstName} ${member.lastName}",
                )
            },
            text = {
                val dScroll = rememberScrollState()
                Column(
                    modifier = Modifier
                        .heightIn(max = 420.dp)
                        .verticalScroll(dScroll),
                    verticalArrangement = Arrangement.spacedBy(8.dp),
                ) {
                    Text(
                        "${statsTr("trainingDetails.birthdate", "Geburtsdatum")}: ${TrainingStatsDerived.formatDateGerman(member.birthDate)}",
                    )
                    val by = TrainingStatsDerived.parseLocalDate(member.birthDate)?.year
                    Text("${statsTr("trainingDetails.birthYear", "Geburtsjahr")}: ${by ?: "–"}")
                    Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
                        Text("${statsTr("trainingDetails.last12Months", "12 Monate")}: ${member.participation12Months}")
                        Text("${statsTr("trainingDetails.last3Months", "3 Monate")}: ${member.participation3Months}")
                        Text("${statsTr("trainingDetails.total", "Gesamt")}: ${member.participationTotal}")
                    }
                    Text(statsTr("trainingDetails.trainingParticipations", "Trainingsteilnahmen"), fontWeight = FontWeight.SemiBold)
                    if (member.trainingDetails.isEmpty()) {
                        Text(statsTr("trainingDetails.noTrainings", "Keine Einträge"), style = MaterialTheme.typography.caption)
                    } else {
                        member.trainingDetails.forEach { t ->
                            Text(
                                "${TrainingStatsDerived.formatDateGerman(t.date)} · ${t.activityName ?: "—"}",
                                style = MaterialTheme.typography.body2,
                            )
                        }
                    }
                }
            },
            confirmButton = {
                TextButton(onClick = { detailMember = null }) {
                    Text(statsTr("common.close", "Schließen"))
                }
            },
        )
    }
}

@Composable
private fun TrainingStatsMainHeader(text: String) {
    Text(text, style = MaterialTheme.typography.h5, fontWeight = FontWeight.SemiBold)
    Spacer(modifier = Modifier.height(12.dp))
}

@Composable
private fun SortHeader(
    label: String,
    field: String,
    sortIcon: (String) -> String,
    onSort: (String) -> Unit,
    minWidth: Dp,
) {
    TextButton(onClick = { onSort(field) }, modifier = Modifier.widthIn(min = minWidth)) {
        Text("$label ${sortIcon(field)}", maxLines = 2, style = MaterialTheme.typography.caption)
    }
}

@Composable
private fun CollapsibleHeader(title: String, expanded: Boolean, onToggle: () -> Unit) {
    TextButton(
        onClick = onToggle,
        modifier = Modifier
            .fillMaxWidth()
            .padding(top = 8.dp),
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Text(title, style = MaterialTheme.typography.subtitle1, fontWeight = FontWeight.SemiBold)
            Text(if (expanded) "▼" else "▶")
        }
    }
}

@Composable
private fun StatMiniCard(title: String, value: String, modifier: Modifier = Modifier) {
    Card(modifier = modifier.padding(4.dp), elevation = 1.dp) {
        Column(modifier = Modifier.padding(10.dp)) {
            Text(title, style = MaterialTheme.typography.caption, maxLines = 3)
            Text(value, style = MaterialTheme.typography.subtitle1, fontWeight = FontWeight.Bold, modifier = Modifier.padding(top = 4.dp))
        }
    }
}

@Composable
private fun StatsSectionTitle(text: String) {
    Spacer(modifier = Modifier.height(16.dp))
    Divider()
    Text(text, style = MaterialTheme.typography.subtitle1, fontWeight = FontWeight.SemiBold, modifier = Modifier.padding(top = 8.dp))
}

@Composable
private fun StatsDetailLine(label: String, value: String) {
    Row(modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)) {
        Text(label, modifier = Modifier.weight(1f), fontWeight = FontWeight.SemiBold)
        Text(value, modifier = Modifier.weight(1f))
    }
}
