package de.trainingstagebuch.app.ui.screens

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.material3.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.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import de.trainingstagebuch.app.R
import de.trainingstagebuch.app.repository.MemberActivityStatItem
import de.trainingstagebuch.app.repository.MemberParticipationItem
import de.trainingstagebuch.app.repository.TrainingDayStatsItem
import de.trainingstagebuch.app.repository.TrainingStatsMember
import de.trainingstagebuch.app.ui.ErrorBanner
import de.trainingstagebuch.app.ui.ErrorSnackbarHost
import de.trainingstagebuch.app.ui.TrainingstagebuchTopBar
import de.trainingstagebuch.app.utils.DateTimeUtils
import de.trainingstagebuch.app.utils.TrainingStatsMetrics
import de.trainingstagebuch.app.viewmodel.SortDirection
import de.trainingstagebuch.app.viewmodel.TrainingStatsSortField
import de.trainingstagebuch.app.viewmodel.TrainingStatsViewModel
import java.util.Locale

@Composable
fun TrainingStatsScreen(
    viewModel: TrainingStatsViewModel = viewModel()
) {
    val state by viewModel.state.collectAsState()
    val context = LocalContext.current
    val snackbarHostState = remember { SnackbarHostState() }
    var dismissedError by remember { mutableStateOf<de.trainingstagebuch.app.utils.UiText?>(null) }

    LaunchedEffect(state.errorMessage) {
        state.errorMessage?.let {
            dismissedError = null
            snackbarHostState.showSnackbar(it.resolve(context))
        }
    }

    val sortedMembers = remember(state.members, state.sortField, state.sortDirection) {
        state.members.sortedWith { a, b ->
            val direction = if (state.sortDirection == SortDirection.Asc) 1 else -1
            when (state.sortField) {
                TrainingStatsSortField.Name -> {
                    val aName = "${a.firstName} ${a.lastName}".lowercase(Locale.getDefault())
                    val bName = "${b.firstName} ${b.lastName}".lowercase(Locale.getDefault())
                    aName.compareTo(bName) * direction
                }

                TrainingStatsSortField.Participation12Months -> (a.participation12Months - b.participation12Months) * direction
                TrainingStatsSortField.Participation3Months -> (a.participation3Months - b.participation3Months) * direction
                TrainingStatsSortField.ParticipationTotal -> (a.participationTotal - b.participationTotal) * direction
                TrainingStatsSortField.LastTraining -> ((a.lastTraining ?: "").compareTo(b.lastTraining ?: "")) * direction
            }
        }
    }

    Scaffold(
        topBar = { TrainingstagebuchTopBar(title = stringResource(R.string.training_stats_title)) },
        snackbarHost = { ErrorSnackbarHost(hostState = snackbarHostState) }
    ) { padding ->
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .padding(padding)
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(10.dp)
        ) {
            item {
                Text(
                    text = stringResource(R.string.training_stats_title),
                    style = MaterialTheme.typography.headlineSmall
                )
            }

            item {
                val currentError = state.errorMessage
                if (currentError != null && currentError != dismissedError) {
                    ErrorBanner(
                        message = currentError.resolve(context),
                        onDismiss = { dismissedError = currentError }
                    )
                }
            }

            item {
                if (state.loading) {
                    Row(
                        modifier = Modifier.fillMaxWidth().padding(vertical = 12.dp),
                        horizontalArrangement = Arrangement.Center
                    ) {
                        CircularProgressIndicator()
                    }
                }
            }

            item {
                if (!state.loading && state.members.isEmpty() && state.trainingDays.isEmpty()) {
                    Button(onClick = viewModel::retryLoad) {
                        Text(stringResource(R.string.common_retry))
                    }
                }
            }

            item {
                StatsCards(days = state.trainingDays, activeMembers = state.members.size)
            }

            item {
                SectionHeader(
                    title = stringResource(R.string.training_stats_training_days),
                    expanded = state.showTrainingDays,
                    onClick = viewModel::toggleTrainingDays
                )
            }

            if (state.showTrainingDays) {
                item {
                    TrainingDaysHeader()
                }
                items(state.trainingDays, key = { it.id }) { day ->
                    TrainingDayRow(day = day)
                }
            }

            item {
                SectionHeader(
                    title = stringResource(R.string.training_stats_members_section),
                    expanded = state.showMembers,
                    onClick = viewModel::toggleMembers
                )
            }

            if (state.showMembers) {
                item {
                    SortButtons(
                        activeField = state.sortField,
                        onSort = viewModel::sortBy
                    )
                }
                item {
                    MembersHeader()
                }
                items(sortedMembers, key = { it.id }) { member ->
                    MemberRow(
                        member = member,
                        onShowDetails = { viewModel.showMemberDetails(member.id) }
                    )
                }
            }
        }
    }

    val selectedMember = state.members.firstOrNull { it.id == state.selectedMemberId }
    if (selectedMember != null) {
        TrainingDetailsDialog(
            member = selectedMember,
            loading = state.detailsLoading,
            errorText = state.detailsErrorMessage?.resolve(context),
            stats = state.memberActivityStats,
            lastParticipations = state.memberLastParticipations,
            onRetry = viewModel::retryMemberDetails,
            onDismiss = viewModel::closeMemberDetails
        )
    }
}

@Composable
private fun StatsCards(days: List<TrainingDayStatsItem>, activeMembers: Int) {
    Column(verticalArrangement = Arrangement.spacedBy(6.dp)) {
        StatsOverviewRow(
            label = stringResource(R.string.training_stats_active_members),
            value = activeMembers.toString()
        )
        StatsOverviewRow(
            label = stringResource(R.string.training_stats_avg_current_month),
            value = TrainingStatsMetrics.averageParticipation(days, TrainingStatsMetrics.Period.CurrentMonth).formatOneDecimal()
        )
        StatsOverviewRow(
            label = stringResource(R.string.training_stats_avg_last_month),
            value = TrainingStatsMetrics.averageParticipation(days, TrainingStatsMetrics.Period.LastMonth).formatOneDecimal()
        )
        StatsOverviewRow(
            label = stringResource(R.string.training_stats_avg_quarter),
            value = TrainingStatsMetrics.averageParticipation(days, TrainingStatsMetrics.Period.QuarterWithMostTrainings).formatOneDecimal()
        )
        StatsOverviewRow(
            label = stringResource(R.string.training_stats_avg_half_year),
            value = TrainingStatsMetrics.averageParticipation(days, TrainingStatsMetrics.Period.HalfYear).formatOneDecimal()
        )
        StatsOverviewRow(
            label = stringResource(R.string.training_stats_avg_year),
            value = TrainingStatsMetrics.averageParticipation(days, TrainingStatsMetrics.Period.Year).formatOneDecimal()
        )
    }
}

@Composable
private fun TrainingDaysHeader() {
    Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) {
        Row(modifier = Modifier.fillMaxWidth().padding(8.dp)) {
            Text(stringResource(R.string.training_stats_date), modifier = Modifier.weight(1f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_weekday), modifier = Modifier.weight(1f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_participants), modifier = Modifier.weight(1f), style = MaterialTheme.typography.labelMedium)
        }
    }
}

@Composable
private fun TrainingDayRow(day: TrainingDayStatsItem) {
    Card {
        Row(modifier = Modifier.fillMaxWidth().padding(8.dp)) {
            Text(formatDate(day.date), modifier = Modifier.weight(1f))
            Text(TrainingStatsMetrics.weekdayLabel(day.date), modifier = Modifier.weight(1f))
            Text(day.participantCount.toString(), modifier = Modifier.weight(1f))
        }
    }
}

@Composable
private fun MembersHeader() {
    Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) {
        Row(modifier = Modifier.fillMaxWidth().padding(8.dp)) {
            Text(stringResource(R.string.training_stats_name), modifier = Modifier.weight(1.4f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_ttr), modifier = Modifier.weight(0.8f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_qttr), modifier = Modifier.weight(0.8f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_birthdate), modifier = Modifier.weight(1f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_sort_12m), modifier = Modifier.weight(0.8f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_sort_3m), modifier = Modifier.weight(0.8f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_sort_total), modifier = Modifier.weight(0.9f), style = MaterialTheme.typography.labelMedium)
            Text(stringResource(R.string.training_stats_last_training), modifier = Modifier.weight(1f), style = MaterialTheme.typography.labelMedium)
        }
    }
}

@Composable
private fun StatsOverviewRow(label: String, value: String) {
    Card {
        Row(
            modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp, horizontal = 10.dp),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Text(label)
            Text(value, style = MaterialTheme.typography.titleMedium)
        }
    }
}

@Composable
private fun SectionHeader(title: String, expanded: Boolean, onClick: () -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable { onClick() }
            .padding(vertical = 4.dp),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(title, style = MaterialTheme.typography.titleMedium)
        Text(
            if (expanded) {
                stringResource(R.string.training_stats_collapse)
            } else {
                stringResource(R.string.training_stats_expand)
            }
        )
    }
}

@Composable
private fun SortButtons(
    activeField: TrainingStatsSortField,
    onSort: (TrainingStatsSortField) -> Unit
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.spacedBy(6.dp)
    ) {
        SortButton(
            text = stringResource(R.string.training_stats_sort_name),
            active = activeField == TrainingStatsSortField.Name,
            onClick = { onSort(TrainingStatsSortField.Name) }
        )
        SortButton(
            text = stringResource(R.string.training_stats_sort_12m),
            active = activeField == TrainingStatsSortField.Participation12Months,
            onClick = { onSort(TrainingStatsSortField.Participation12Months) }
        )
        SortButton(
            text = stringResource(R.string.training_stats_sort_3m),
            active = activeField == TrainingStatsSortField.Participation3Months,
            onClick = { onSort(TrainingStatsSortField.Participation3Months) }
        )
        SortButton(
            text = stringResource(R.string.training_stats_sort_total),
            active = activeField == TrainingStatsSortField.ParticipationTotal,
            onClick = { onSort(TrainingStatsSortField.ParticipationTotal) }
        )
        SortButton(
            text = stringResource(R.string.training_stats_last_training),
            active = activeField == TrainingStatsSortField.LastTraining,
            onClick = { onSort(TrainingStatsSortField.LastTraining) }
        )
    }
}

@Composable
private fun SortButton(text: String, active: Boolean, onClick: () -> Unit) {
    Button(onClick = onClick, enabled = !active) {
        Text(text)
    }
}

@Composable
private fun MemberRow(member: TrainingStatsMember, onShowDetails: () -> Unit) {
    Card {
        Column(modifier = Modifier.fillMaxWidth().padding(8.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
            Row(modifier = Modifier.fillMaxWidth()) {
                Text("${member.firstName} ${member.lastName}", modifier = Modifier.weight(1.4f))
                Text(member.ttr?.toString() ?: "-", modifier = Modifier.weight(0.8f))
                Text(member.qttr?.toString() ?: "-", modifier = Modifier.weight(0.8f))
                Text(formatDate(member.birthDate), modifier = Modifier.weight(1f))
                Text(member.participation12Months.toString(), modifier = Modifier.weight(0.8f))
                Text(member.participation3Months.toString(), modifier = Modifier.weight(0.8f))
                Text(member.participationTotal.toString(), modifier = Modifier.weight(0.9f))
                Text(formatDate(member.lastTraining), modifier = Modifier.weight(1f))
            }
            TextButton(onClick = onShowDetails, modifier = Modifier.align(Alignment.End)) {
                Text(stringResource(R.string.training_stats_show_details))
            }
        }
    }
}

@Composable
private fun TrainingDetailsDialog(
    member: TrainingStatsMember,
    loading: Boolean,
    errorText: String?,
    stats: List<MemberActivityStatItem>,
    lastParticipations: List<MemberParticipationItem>,
    onRetry: () -> Unit,
    onDismiss: () -> Unit
) {
    AlertDialog(
        onDismissRequest = onDismiss,
        title = {
            Text(
                text = stringResource(
                    R.string.training_stats_member_name_value,
                    member.firstName,
                    member.lastName
                )
            )
        },
        text = {
            Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                Text(stringResource(R.string.training_stats_detail_ttr, member.ttr?.toString() ?: "-"))
                Text(stringResource(R.string.training_stats_detail_qttr, member.qttr?.toString() ?: "-"))
                Text(stringResource(R.string.training_stats_detail_birthdate, formatDate(member.birthDate)))
                Text(stringResource(R.string.training_stats_detail_p12, member.participation12Months))
                Text(stringResource(R.string.training_stats_detail_p3, member.participation3Months))
                Text(stringResource(R.string.training_stats_detail_total, member.participationTotal))
                Text(stringResource(R.string.training_stats_detail_last, formatDate(member.lastTraining)))

                if (loading) {
                    CircularProgressIndicator()
                } else if (!errorText.isNullOrBlank()) {
                    Text(errorText, color = MaterialTheme.colorScheme.error)
                    Button(onClick = onRetry) {
                        Text(stringResource(R.string.common_retry))
                    }
                } else {
                    Text(stringResource(R.string.training_stats_activity_stats_title), style = MaterialTheme.typography.titleSmall)
                    if (stats.isEmpty()) {
                        Text(stringResource(R.string.training_stats_no_activity_stats))
                    } else {
                        stats.forEach {
                            Text(stringResource(R.string.training_stats_activity_stats_item, it.activity, it.count))
                        }
                    }

                    Text(
                        stringResource(R.string.training_stats_last_participations_title),
                        style = MaterialTheme.typography.titleSmall,
                        modifier = Modifier.padding(top = 4.dp)
                    )
                    if (lastParticipations.isEmpty()) {
                        Text(stringResource(R.string.training_stats_no_last_participations))
                    } else {
                        lastParticipations.forEach {
                            Text(
                                stringResource(
                                    R.string.training_stats_last_participation_item,
                                    formatDate(it.date),
                                    it.activity
                                )
                            )
                        }
                    }
                }
            }
        },
        confirmButton = {
            TextButton(onClick = onDismiss) {
                Text(stringResource(R.string.training_stats_close))
            }
        }
    )
}

private fun Double.formatOneDecimal(): String = String.format(Locale.getDefault(), "%.1f", this)

private fun formatDate(date: String?): String {
    val parsed = TrainingStatsMetrics.parseDate(date) ?: return "-"
    return DateTimeUtils.formatUiDate(parsed)
}
