package de.trainingstagebuch.app.ui.screens

import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
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.CircularProgressIndicator
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
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.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.Modifier
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.viewmodel.TournamentMode
import de.trainingstagebuch.app.viewmodel.TournamentTopTab
import de.trainingstagebuch.app.viewmodel.TournamentsViewModel
import de.trainingstagebuch.app.ui.ErrorBanner
import de.trainingstagebuch.app.repository.MemberItem
import de.trainingstagebuch.app.repository.OfficialCompetitionItem
import de.trainingstagebuch.app.repository.OfficialParticipationItem

@Composable
fun TournamentsScreen(
    viewModel: TournamentsViewModel = viewModel()
) {
    val state by viewModel.state.collectAsState()
    val context = LocalContext.current
    var dismissedError by remember { mutableStateOf<de.trainingstagebuch.app.utils.UiText?>(null) }
    var pickedFileName by rememberSaveable { mutableStateOf("") }
    var pickedBytes by remember { mutableStateOf<ByteArray?>(null) }
    val pdfPicker = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        if (uri == null) return@rememberLauncherForActivityResult
        val bytes = context.contentResolver.openInputStream(uri)?.use { it.readBytes() } ?: return@rememberLauncherForActivityResult
        pickedBytes = bytes
        pickedFileName = uri.lastPathSegment?.substringAfterLast('/')?.ifBlank { "official.pdf" } ?: "official.pdf"
    }
    LaunchedEffect(state.activeTab) {
        if (state.activeTab != TournamentTopTab.Official) {
            pickedFileName = ""
            pickedBytes = null
        }
    }

    Column(
        modifier = Modifier.fillMaxSize().padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Text(
            text = stringResource(R.string.tournaments_title),
            style = MaterialTheme.typography.headlineSmall
        )
        TournamentTopTabs(
            active = state.activeTab,
            onSelect = viewModel::setTab
        )
        val currentError = state.errorMessage
        if (currentError != null && currentError != dismissedError) {
            ErrorBanner(
                message = currentError.resolve(context),
                onDismiss = { dismissedError = currentError }
            )
        }
        state.successMessage?.let {
            Text(
                text = it.resolve(context),
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.primary
            )
        }
        when (state.activeTab) {
            TournamentTopTab.Internal -> TournamentTabScreen(mode = TournamentMode.Internal)
            TournamentTopTab.External -> TournamentTabScreen(mode = TournamentMode.External)
            TournamentTopTab.Mini -> TournamentTabScreen(mode = TournamentMode.Mini)
            TournamentTopTab.Official -> OfficialTournamentsContent(
                loading = state.officialLoading,
                actionLoading = state.officialActionLoading,
                total = state.officialSummary?.total ?: state.officialTournaments.size,
                planned = state.officialSummary?.plannedParticipations ?: 0,
                tournaments = state.officialTournaments,
                selectedTournamentId = state.selectedOfficialTournamentId,
                detail = state.officialDetail,
                members = state.officialMembers,
                onPickPdf = { pdfPicker.launch("application/pdf") },
                pickedFileName = pickedFileName,
                onUpload = {
                    val bytes = pickedBytes ?: return@OfficialTournamentsContent
                    viewModel.uploadOfficialPdf(
                        fileName = pickedFileName.ifBlank { "official.pdf" },
                        bytes = bytes
                    )
                    pickedBytes = null
                    pickedFileName = ""
                },
                onSelectTournament = viewModel::loadOfficialDetail,
                onDeleteTournament = viewModel::deleteOfficialTournament,
                onToggleWants = viewModel::toggleOfficialWants,
                onSetStatus = viewModel::setOfficialStatus,
                onPlacementChange = viewModel::setOfficialPlacement,
                onRetry = viewModel::retryOfficial
            )
        }
    }
}

@Composable
private fun TournamentTopTabs(
    active: TournamentTopTab,
    onSelect: (TournamentTopTab) -> Unit
) {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(6.dp)
    ) {
        Button(onClick = { onSelect(TournamentTopTab.Internal) }, enabled = active != TournamentTopTab.Internal) {
            Text(stringResource(R.string.tournaments_tab_internal))
        }
        Button(onClick = { onSelect(TournamentTopTab.External) }, enabled = active != TournamentTopTab.External) {
            Text(stringResource(R.string.tournaments_tab_external))
        }
        Button(onClick = { onSelect(TournamentTopTab.Mini) }, enabled = active != TournamentTopTab.Mini) {
            Text(stringResource(R.string.tournaments_tab_mini))
        }
        Button(onClick = { onSelect(TournamentTopTab.Official) }, enabled = active != TournamentTopTab.Official) {
            Text(stringResource(R.string.tournaments_tab_official))
        }
    }
}

@Composable
private fun OfficialTournamentsContent(
    loading: Boolean,
    actionLoading: Boolean,
    total: Int,
    planned: Int,
    tournaments: List<de.trainingstagebuch.app.repository.OfficialTournamentItem>,
    selectedTournamentId: String?,
    detail: de.trainingstagebuch.app.repository.OfficialTournamentDetailData?,
    members: List<MemberItem>,
    onPickPdf: () -> Unit,
    pickedFileName: String,
    onUpload: () -> Unit,
    onSelectTournament: (String) -> Unit,
    onDeleteTournament: (String) -> Unit,
    onToggleWants: (competitionId: Int, memberId: String, wants: Boolean) -> Unit,
    onSetStatus: (competitionId: Int, memberId: String, action: String) -> Unit,
    onPlacementChange: (competitionId: Int, memberId: String, placement: String) -> Unit,
    onRetry: () -> Unit
) {
    if (loading || actionLoading) {
        CircularProgressIndicator()
    }
    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            OutlinedButton(onClick = onPickPdf) {
                Text(stringResource(R.string.official_tournaments_pick_pdf))
            }
            Button(onClick = onUpload, enabled = pickedFileName.isNotBlank()) {
                Text(stringResource(R.string.official_tournaments_upload_pdf))
            }
        }
        if (pickedFileName.isNotBlank()) {
            Text(
                text = pickedFileName,
                style = MaterialTheme.typography.bodySmall
            )
        }
        Text(
            text = stringResource(R.string.official_tournaments_summary_line, total, planned),
            style = MaterialTheme.typography.bodyMedium
        )
        if (tournaments.isEmpty()) {
            Text(stringResource(R.string.official_tournaments_empty))
            Button(onClick = onRetry) { Text(stringResource(R.string.home_retry)) }
        } else {
            LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                items(tournaments, key = { it.id }) { item ->
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.SpaceBetween
                    ) {
                        OutlinedButton(
                            onClick = { onSelectTournament(item.id) },
                            modifier = Modifier.fillMaxWidth(),
                            enabled = selectedTournamentId != item.id
                        ) {
                            Text(
                                text = stringResource(
                                    R.string.official_tournaments_item_line,
                                    item.name,
                                    item.date ?: "-",
                                    item.location ?: "-"
                                )
                            )
                        }
                        OutlinedButton(onClick = { onDeleteTournament(item.id) }) {
                            Text(stringResource(R.string.official_tournaments_delete))
                        }
                    }
                }
            }
        }

        if (detail != null) {
            Text(
                text = detail.title ?: stringResource(R.string.tournaments_tab_official),
                style = MaterialTheme.typography.titleMedium
            )
            Text(
                text = detail.termin ?: "-",
                style = MaterialTheme.typography.bodySmall
            )
            detail.competitions.forEach { competition ->
                OfficialCompetitionCard(
                    competition = competition,
                    participations = detail.participation,
                    members = members,
                    onToggleWants = onToggleWants,
                    onSetStatus = onSetStatus,
                    onPlacementChange = onPlacementChange
                )
            }
        }
    }
}

@Composable
private fun OfficialCompetitionCard(
    competition: OfficialCompetitionItem,
    participations: List<OfficialParticipationItem>,
    members: List<MemberItem>,
    onToggleWants: (competitionId: Int, memberId: String, wants: Boolean) -> Unit,
    onSetStatus: (competitionId: Int, memberId: String, action: String) -> Unit,
    onPlacementChange: (competitionId: Int, memberId: String, placement: String) -> Unit
) {
    Column(
        modifier = Modifier.fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        Text(
            text = "${competition.name} | ${competition.startTime ?: "-"} | ${competition.entryFee ?: "-"}",
            style = MaterialTheme.typography.titleSmall
        )
        val rows = participations.filter { it.competitionId == competition.id }
        if (rows.isEmpty()) {
            Text(stringResource(R.string.official_tournaments_no_participations))
        } else {
            rows.forEach { p ->
                val member = members.firstOrNull { it.id == p.memberId }
                val memberName = member?.displayName ?: p.memberId
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.spacedBy(6.dp)
                ) {
                    OutlinedButton(onClick = { onToggleWants(competition.id, p.memberId, !p.wants) }) {
                        Text(
                            if (p.wants) {
                                stringResource(R.string.official_tournaments_wants)
                            } else {
                                stringResource(R.string.official_tournaments_not_wants)
                            }
                        )
                    }
                    OutlinedButton(onClick = {
                        onSetStatus(
                            competition.id,
                            p.memberId,
                            when {
                                !p.registered && !p.participated -> "register"
                                p.registered && !p.participated -> "participate"
                                else -> "reset"
                            }
                        )
                    }) {
                        Text(memberName)
                    }
                    OutlinedTextField(
                        value = p.placement.orEmpty(),
                        onValueChange = { onPlacementChange(competition.id, p.memberId, it) },
                        label = { Text(stringResource(R.string.official_tournaments_placement)) },
                        modifier = Modifier.fillMaxWidth(),
                        singleLine = true
                    )
                }
            }
        }
    }
}
