package ru.durakscore.app

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import java.util.Date
import java.util.Locale

data class MainScorePlayer(
    val id: String,
    val name: String,
    val sortOrder: Int,
    val losses: Int?
)

private data class MainScoreGame(
    val id: String,
    val loserId: String?,
    val finishedAt: Timestamp?
)

private data class MainScoreRecord(
    val iconRes: Int,
    val title: String,
    val playerName: String,
    val value: String
)

private val MainScoreCard =
    PokerPalette.Panel

private val MainScoreCardStrong =
    PokerPalette.PanelStrong

private val MainScoreBorder =
    PokerPalette.PanelBorder

private val MainScoreGreen =
    PokerPalette.Good

private val MainScoreRed =
    PokerPalette.Bad

private val MainScoreGold =
    PokerPalette.Gold

private val MainScoreMuted =
    PokerPalette.TextSecondary

private fun playerSuit(
    playerId: String
): String =
    when (playerId) {
        "denis" -> "♠"
        "dmitry" -> "♣"
        "rybka" -> "♥"
        "masha" -> "♦"
        else -> "🃏"
    }

private fun parseMainScoreGame(
    game: ServerFinishedGame
): MainScoreGame? {

    if (
        game.isTest !=
        TEST_MODE
    ) {
        return null
    }

    if (
        game.gameType !=
        "classic"
    ) {
        return null
    }

    return MainScoreGame(
        id =
            game.id,
        loserId =
            game.loserId
                .takeIf {
                    it.isNotBlank()
                },
        finishedAt =
            game.finishedAtEpochMillis
                .takeIf {
                    it > 0L
                }
                ?.let {
                    Timestamp(
                        Date(
                            it
                        )
                    )
                }
    )
}

private fun calculateLongestLossStreak(
    games: List<MainScoreGame>,
    playerId: String
): Int {

    var current =
        0

    var best =
        0

    games
        .sortedBy {
            it.finishedAt
                ?.seconds
                ?: 0L
        }
        .forEach {
            game ->

            if (
                game.loserId ==
                playerId
            ) {
                current++

                if (
                    current >
                    best
                ) {
                    best =
                        current
                }
            } else {
                current =
                    0
            }
        }

    return best
}

private fun formatRate(
    losses: Int,
    games: Int
): String {

    if (
        games <=
        0
    ) {
        return "—"
    }

    val rate =
        losses.toDouble() /
            games.toDouble()

    return String.format(
        Locale.US,
        "%.2f",
        rate
    )
}

private fun lossesWord(
    count: Int
): String {

    val mod100 =
        count % 100

    if (
        mod100 in
        11..14
    ) {
        return "поражений"
    }

    return when (
        count % 10
    ) {
        1 ->
            "поражение"

        2, 3, 4 ->
            "поражения"

        else ->
            "поражений"
    }
}

@Composable
fun MainScoreScreen(
    access: UserAccess,
    onBack: () -> Unit
) {

    BackHandler(
        onBack =
            onBack
    )

    val canEdit =
        access.role ==
            "admin" ||
            access.role ==
            "scorekeeper"

    var players by remember {
        mutableStateOf<List<MainScorePlayer>>(
            emptyList()
        )
    }

    var playerData by remember {
        mutableStateOf<Map<String, Pair<String, Int>>>(
            emptyMap()
        )
    }

    var scoreData by remember {
        mutableStateOf<Map<String, Int>>(
            emptyMap()
        )
    }

    var games by remember {
        mutableStateOf<List<MainScoreGame>>(
            emptyList()
        )
    }

    var playersLoaded by remember {
        mutableStateOf(false)
    }

    var scoresLoaded by remember {
        mutableStateOf(false)
    }

    var gamesLoaded by remember {
        mutableStateOf(false)
    }

    var errorText by remember {
        mutableStateOf<String?>(
            null
        )
    }

    var editingPlayer by remember {
        mutableStateOf<MainScorePlayer?>(
            null
        )
    }

    var editValue by remember {
        mutableStateOf("")
    }

    var editError by remember {
        mutableStateOf<String?>(
            null
        )
    }

    var isSaving by remember {
        mutableStateOf(false)
    }

    fun rebuildList() {

        players =
            playerData.map {
                    (id, data) ->

                MainScorePlayer(
                    id =
                        id,
                    name =
                        data.first,
                    sortOrder =
                        data.second,
                    losses =
                        scoreData[id]
                )
            }
                .sortedBy {
                    it.sortOrder
                }
    }

    LaunchedEffect(Unit) {

        val user =
            DurakAuthSession.current()

        if (
            user ==
            null
        ) {
            errorText =
                "Пользователь не авторизован"

            playersLoaded =
                true

            scoresLoaded =
                true

            gamesLoaded =
                true

            return@LaunchedEffect
        }

        DurakServerApi
            .loadMainScore(
                user =
                    user,
                onSuccess = {
                        serverPlayers ->

                    val corePlayers =
                        serverPlayers
                            .filter {
                                it.isCore
                            }

                    playerData =
                        corePlayers
                            .associate {
                                it.id to
                                    Pair(
                                        it.name,
                                        it.sortOrder
                                    )
                            }

                    scoreData =
                        corePlayers
                            .associate {
                                it.id to
                                    it.losses
                            }

                    playersLoaded =
                        true

                    scoresLoaded =
                        true

                    rebuildList()
                },
                onError = {
                        message ->

                    errorText =
                        message.ifBlank {
                            "Не удалось загрузить общий счёт"
                        }

                    playersLoaded =
                        true

                    scoresLoaded =
                        true
                }
            )

        DurakServerApi
            .loadFinishedGames(
                user =
                    user,
                onSuccess = {
                        serverGames ->

                    games =
                        serverGames
                            .mapNotNull {
                                parseMainScoreGame(
                                    it
                                )
                            }

                    gamesLoaded =
                        true
                },
                onError = {
                    /*
                     * Основной счёт всё равно показываем.
                     * Исторические карточки просто не считаем,
                     * если отдельный запрос истории не удался.
                     */
                    gamesLoaded =
                        true
                }
            )
    }

    val isLoading =
        !playersLoaded ||
        !scoresLoaded ||
        !gamesLoaded

    val scoreInitialized =
        players.isNotEmpty() &&
            players.all {
                it.losses !=
                    null
            }

    val rankedPlayers =
        remember(
            players
        ) {
            players
                .filter {
                    it.losses !=
                        null
                }
                .sortedWith(
                    compareBy<MainScorePlayer> {
                        it.losses
                            ?: Int.MAX_VALUE
                    }
                        .thenBy {
                            it.sortOrder
                        }
                )
        }

    val minLosses =
        rankedPlayers
            .minOfOrNull {
                it.losses
                    ?: Int.MAX_VALUE
            }

    val leaders =
        if (
            minLosses !=
            null
        ) {
            rankedPlayers
                .filter {
                    it.losses ==
                        minLosses
                }
        } else {
            emptyList()
        }

    val leader =
        leaders
            .firstOrNull()

    val appLossesByPlayer =
        remember(
            games
        ) {
            games
                .mapNotNull {
                    it.loserId
                }
                .groupingBy {
                    it
                }
                .eachCount()
        }

    val leaderAppLosses =
        leader
            ?.let {
                appLossesByPlayer[
                    it.id
                ] ?: 0
            }
            ?: 0

    val leaderRate =
        formatRate(
            losses =
                leaderAppLosses,
            games =
                games.size
        )

    val maxLosses =
        rankedPlayers
            .maxOfOrNull {
                it.losses
                    ?: 0
            }

    val worstPlayers =
        if (
            maxLosses !=
            null
        ) {
            rankedPlayers
                .filter {
                    it.losses ==
                        maxLosses
                }
        } else {
            emptyList()
        }

    val lossStreaksByPlayer =
        rankedPlayers
            .map {
                player ->

                player to
                    calculateLongestLossStreak(
                        games =
                            games,
                        playerId =
                            player.id
                    )
            }

    val maxLossStreak =
        lossStreaksByPlayer
            .maxOfOrNull {
                it.second
            }
            ?: 0

    val longestStreakPlayers =
        if (
            maxLossStreak > 0
        ) {
            lossStreaksByPlayer
                .filter {
                    it.second ==
                        maxLossStreak
                }
        } else {
            emptyList()
        }

    val appBestRateLosses =
        if (
            games.isNotEmpty()
        ) {
            rankedPlayers
                .minOfOrNull {
                    player ->
                    appLossesByPlayer[
                        player.id
                    ] ?: 0
                }
                ?: 0
        } else {
            0
        }

    val appBestRatePlayers =
        if (
            games.isNotEmpty()
        ) {
            rankedPlayers
                .filter {
                    player ->
                    (
                        appLossesByPlayer[
                            player.id
                        ] ?: 0
                        ) ==
                        appBestRateLosses
                }
        } else {
            emptyList()
        }

    val records =
        buildList {

            if (
                leaders.isNotEmpty() &&
                minLosses !=
                null
            ) {
                add(
                    MainScoreRecord(
                        iconRes =
                            R.drawable.main_score_trophy,
                        title =
                            "Меньше всего поражений",
                        playerName =
                            leaders.joinToString(
                                separator = " и "
                            ) {
                                it.name
                            },
                        value =
                            minLosses.toString()
                    )
                )
            }

            if (
                worstPlayers.isNotEmpty() &&
                maxLosses !=
                null
            ) {
                add(
                    MainScoreRecord(
                        iconRes =
                            R.drawable.main_score_dual_skull,
                        title =
                            "Больше всего поражений",
                        playerName =
                            worstPlayers.joinToString(
                                separator = " и "
                            ) {
                                it.name
                            },
                        value =
                            maxLosses.toString()
                    )
                )
            }

            if (
                longestStreakPlayers.isNotEmpty() &&
                maxLossStreak >
                0
            ) {
                add(
                    MainScoreRecord(
                        iconRes =
                            R.drawable.main_score_flame_jester,
                        title =
                            "Самая длинная серия поражений",
                        playerName =
                            longestStreakPlayers
                                .joinToString(
                                    separator = " и "
                                ) {
                                    it.first.name
                                },
                        value =
                            if (
                                longestStreakPlayers.size >
                                1
                            ) {
                                "по $maxLossStreak подряд"
                            } else {
                                "$maxLossStreak подряд"
                            }
                    )
                )
            }

            if (
                appBestRatePlayers.isNotEmpty() &&
                games.isNotEmpty()
            ) {
                add(
                    MainScoreRecord(
                        iconRes =
                            R.drawable.main_score_shield_jester,
                        title =
                            "Реже всех проигрывает",
                        playerName =
                            appBestRatePlayers
                                .joinToString(
                                    separator = " и "
                                ) {
                                    it.name
                                },
                        value =
                            formatRate(
                                losses =
                                    appBestRateLosses,
                                games =
                                    games.size
                            )
                    )
                )
            }
        }

    PokerScreen {

        /*
         * Верх концепта 1:
         * стрелка — заголовок — инфо.
         */
        Row(
            modifier =
                Modifier.fillMaxWidth(),
            verticalAlignment =
                Alignment.CenterVertically
        ) {

            Text(
                text =
                    "←",
                color =
                    MainScoreGold,
                fontSize =
                    34.sp,
                fontWeight =
                    FontWeight.Light,
                modifier =
                    Modifier
                        .clickable {
                            onBack()
                        }
                        .padding(
                            end = 12.dp
                        )
            )

            Text(
                text =
                    "Общий счёт",
                color =
                    PokerPalette.TextPrimary,
                fontSize =
                    30.sp,
                fontFamily =
                    PokerDisplayFont,
                fontWeight =
                    FontWeight.Bold,
                lineHeight =
                    34.sp,
                maxLines =
                    2,
                textAlign =
                    TextAlign.Center,
                modifier =
                    Modifier.weight(
                        1f
                    )
            )

            Text(
                text =
                    "ⓘ",
                color =
                    MainScoreGold,
                fontSize =
                    27.sp
            )
        }

        Spacer(
            modifier =
                Modifier.height(
                    18.dp
                )
        )

        if (
            TEST_MODE
        ) {

            Surface(
                shape =
                    RoundedCornerShape(
                        18.dp
                    ),
                color =
                    MainScoreCard,
                border =
                    BorderStroke(
                        1.dp,
                        MainScoreGold
                    ),
                modifier =
                    Modifier.fillMaxWidth()
            ) {

                Text(
                    text =
                        "ТЕСТОВЫЙ РЕЖИМ • тестовые партии не изменяют настоящий общий счёт",
                    modifier =
                        Modifier.padding(
                            14.dp
                        ),
                    color =
                        MainScoreGold,
                    fontSize =
                        13.sp,
                    fontWeight =
                        FontWeight.SemiBold
                )
            }

            Spacer(
                modifier =
                    Modifier.height(
                        14.dp
                    )
            )
        }

        when {

            isLoading -> {

                Row(
                    modifier =
                        Modifier.fillMaxWidth(),
                    horizontalArrangement =
                        Arrangement.Center
                ) {

                    CircularProgressIndicator(
                        color =
                            MainScoreGold
                    )
                }
            }

            errorText !=
                null -> {

                Surface(
                    shape =
                        RoundedCornerShape(
                            20.dp
                        ),
                    color =
                        MainScoreCard,
                    border =
                        BorderStroke(
                            1.dp,
                            MainScoreBorder
                        ),
                    modifier =
                        Modifier.fillMaxWidth()
                ) {

                    Text(
                        text =
                            errorText!!,
                        modifier =
                            Modifier.padding(
                                18.dp
                            ),
                        color =
                            PokerPalette.Danger,
                        fontSize =
                            16.sp
                    )
                }
            }

            else -> {

                if (
                    !scoreInitialized
                ) {

                    Surface(
                        shape =
                            RoundedCornerShape(
                                20.dp
                            ),
                        color =
                            MainScoreCard,
                        border =
                            BorderStroke(
                                1.dp,
                                MainScoreBorder
                            ),
                        modifier =
                            Modifier.fillMaxWidth()
                    ) {

                        Text(
                            text =
                                "Стартовый счёт ещё не внесён",
                            modifier =
                                Modifier.padding(
                                    18.dp
                                ),
                            color =
                                PokerPalette.TextPrimary,
                            fontSize =
                                17.sp,
                            fontWeight =
                                FontWeight.Bold
                        )
                    }

                    Spacer(
                        modifier =
                            Modifier.height(
                                14.dp
                            )
                    )
                }

                if (
                    leader !=
                    null &&
                    minLosses !=
                    null
                ) {

                    LeaderCard(
                        leader =
                            leader,
                        leaderCount =
                            leaders.size,
                        losses =
                            minLosses
                    )

                    Spacer(
                        modifier =
                            Modifier.height(
                                14.dp
                            )
                    )

                    BoxWithConstraints(
                        modifier = Modifier.fillMaxWidth()
                    ) {
                        val stackStats =
                            maxWidth < 340.dp ||
                                LocalDensity.current.fontScale >= 1.28f

                        if (stackStats) {
                            Column(
                                modifier = Modifier.fillMaxWidth(),
                                verticalArrangement =
                                    Arrangement.spacedBy(10.dp)
                            ) {
                                MiniStatCard(
                                    modifier = Modifier.fillMaxWidth(),
                                    iconRes =
                                        R.drawable.main_score_hat,
                                    title =
                                        "ПАРТИЙ В ПРИЛОЖЕНИИ",
                                    value =
                                        games.size.toString()
                                )

                                MiniStatCard(
                                    modifier = Modifier.fillMaxWidth(),
                                    iconRes =
                                        R.drawable.main_score_skull_hat,
                                    title =
                                        "ПОРАЖЕНИЙ ЛИДЕРА НА ПАРТИЮ",
                                    value =
                                        leaderRate
                                )
                            }
                        } else {
                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement =
                                    Arrangement.spacedBy(10.dp)
                            ) {
                                MiniStatCard(
                                    modifier = Modifier.weight(1f),
                                    iconRes =
                                        R.drawable.main_score_hat,
                                    title =
                                        "ПАРТИЙ В ПРИЛОЖЕНИИ",
                                    value =
                                        games.size.toString()
                                )

                                MiniStatCard(
                                    modifier = Modifier.weight(1f),
                                    iconRes =
                                        R.drawable.main_score_skull_hat,
                                    title =
                                        "ПОРАЖЕНИЙ ЛИДЕРА\nНА ПАРТИЮ",
                                    value =
                                        leaderRate
                                )
                            }
                        }
                    }

                    Spacer(
                        modifier =
                            Modifier.height(
                                14.dp
                            )
                    )

                    RankingCard(
                        players =
                            rankedPlayers,
                        canEdit =
                            canEdit,
                        onEdit = {
                                player ->

                            editingPlayer =
                                player

                            editValue =
                                player.losses
                                    ?.toString()
                                    ?: ""

                            editError =
                                null
                        }
                    )

                    Spacer(
                        modifier =
                            Modifier.height(
                                16.dp
                            )
                    )

                    HistoryCard(
                        records =
                            records
                    )

                    Spacer(
                        modifier =
                            Modifier.height(
                                12.dp
                            )
                    )

                    Surface(
                        shape =
                            RoundedCornerShape(
                                18.dp
                            ),
                        color =
                            MainScoreCard,
                        border =
                            BorderStroke(
                                1.dp,
                                MainScoreBorder
                            ),
                        modifier =
                            Modifier.fillMaxWidth()
                    ) {

                        Row(
                            modifier =
                                Modifier.padding(
                                    horizontal =
                                        14.dp,
                                    vertical =
                                        12.dp
                                ),
                            verticalAlignment =
                                Alignment.CenterVertically
                        ) {

                            Image(
                                painter =
                                    painterResource(
                                        id =
                                            R.drawable.main_score_footer_jester
                                    ),
                                contentDescription =
                                    null,
                                modifier =
                                    Modifier.size(
                                        50.dp
                                    )
                            )

                            Spacer(
                                modifier =
                                    Modifier.size(
                                        10.dp
                                    )
                            )

                            Column(
                                modifier =
                                    Modifier.weight(
                                        1f
                                    ),
                                horizontalAlignment =
                                    Alignment.CenterHorizontally
                            ) {

                            Text(
                                text =
                                    "Поражения учитываются только в классических партиях.",
                                color =
                                    MainScoreMuted,
                                fontSize =
                                    13.sp,
                                textAlign =
                                    TextAlign.Center
                            )

                            Spacer(
                                modifier =
                                    Modifier.height(
                                        4.dp
                                    )
                            )

                            Text(
                                text =
                                    "Меньше поражений — лучше.",
                                color =
                                    MainScoreGold,
                                fontSize =
                                    13.sp,
                                fontWeight =
                                    FontWeight.Bold
                            )
                            }
                        }
                    }

                    Spacer(
                        modifier =
                            Modifier.height(
                                16.dp
                            )
                    )

                    PokerBottomBackButton(
                        onClick =
                            onBack
                    )
                }
            }
        }
    }

    /*
     * Сохраняем старую ручную корректировку,
     * но теперь она открывается тапом по игроку
     * в рейтинге — интерфейс чище.
     */
    if (
        editingPlayer !=
        null
    ) {

        val player =
            editingPlayer!!

        AlertDialog(
            onDismissRequest = {
                if (
                    !isSaving
                ) {
                    editingPlayer =
                        null
                }
            },
            title = {
                Text(
                    "Изменить счёт: ${player.name}"
                )
            },
            text = {

                Column {

                    Text(
                        "Сейчас: ${player.losses}"
                    )

                    Spacer(
                        modifier =
                            Modifier.height(
                                12.dp
                            )
                    )

                    OutlinedTextField(
                        value =
                            editValue,
                        onValueChange = {
                                value ->

                            editValue =
                                value.filter {
                                    it.isDigit()
                                }

                            editError =
                                null
                        },
                        label = {
                            Text(
                                "Новый счёт"
                            )
                        },
                        keyboardOptions =
                            KeyboardOptions(
                                keyboardType =
                                    KeyboardType.Number
                            ),
                        singleLine =
                            true
                    )

                    if (
                        TEST_MODE
                    ) {

                        Spacer(
                            modifier =
                                Modifier.height(
                                    12.dp
                                )
                        )

                        Text(
                            "Тестовый режим: изменение реального счёта заблокировано."
                        )
                    }

                    if (
                        editError !=
                        null
                    ) {

                        Spacer(
                            modifier =
                                Modifier.height(
                                    12.dp
                                )
                        )

                        Text(
                            editError!!
                        )
                    }
                }
            },
            confirmButton = {

                Button(
                    enabled =
                        !TEST_MODE &&
                            !isSaving,
                    colors =
                        ButtonDefaults
                            .buttonColors(
                                containerColor =
                                    MainScoreGold,
                                contentColor =
                                    Color(
                                        0xFF1C180E
                                    )
                            ),
                    onClick = {

                        val newValue =
                            editValue
                                .toIntOrNull()

                        if (
                            newValue ==
                            null
                        ) {
                            editError =
                                "Введите число"
                        } else {

                            isSaving =
                                true

                            MainScoreRepository
                                .correctScore(
                                    playerId =
                                        player.id,
                                    playerName =
                                        player.name,
                                    newValue =
                                        newValue,
                                    changedByUid =
                                        DurakAuthSession.current()
                                            ?.uid
                                            .orEmpty(),
                                    changedByName =
                                        access.name,
                                    onSuccess = {
                                        isSaving =
                                            false

                                        editingPlayer =
                                            null
                                    },
                                    onError = {
                                            message ->

                                        isSaving =
                                            false

                                        editError =
                                            message
                                    }
                                )
                        }
                    }
                ) {

                    Text(
                        if (
                            isSaving
                        ) {
                            "Сохраняю..."
                        } else {
                            "Сохранить"
                        }
                    )
                }
            },
            dismissButton = {

                TextButton(
                    enabled =
                        !isSaving,
                    onClick = {
                        editingPlayer =
                            null
                    }
                ) {
                    Text(
                        "Отмена"
                    )
                }
            }
        )
    }
}

@Composable
private fun LeaderCard(
    leader: MainScorePlayer,
    leaderCount: Int,
    losses: Int
) {
    val fontScale = LocalDensity.current.fontScale
    val heroMinHeight =
        when {
            fontScale >= 1.30f -> 218.dp
            fontScale >= 1.15f -> 194.dp
            else -> 178.dp
        }

    Surface(
        modifier = Modifier.fillMaxWidth(),
        color = PokerPalette.PanelStrong,
        border =
            BorderStroke(
                width = 1.dp,
                color = MainScoreBorder
            ),
        shape = RoundedCornerShape(24.dp)
    ) {
        Box(
            modifier =
                Modifier
                    .fillMaxWidth()
                    .heightIn(min = heroMinHeight)
        ) {
            Image(
                painter =
                    painterResource(
                        id = R.drawable.main_score_leader_jester
                    ),
                contentDescription = null,
                contentScale = ContentScale.Fit,
                modifier =
                    Modifier
                        .align(Alignment.CenterEnd)
                        .padding(end = 2.dp)
                        .size(
                            width =
                                if (fontScale >= 1.25f) {
                                    96.dp
                                } else {
                                    112.dp
                                },
                            height =
                                if (fontScale >= 1.25f) {
                                    142.dp
                                } else {
                                    154.dp
                                }
                        )
            )

            Row(
                modifier =
                    Modifier
                        .fillMaxWidth()
                        .padding(
                            start = 16.dp,
                            top = 18.dp,
                            end =
                                if (fontScale >= 1.25f) {
                                    72.dp
                                } else {
                                    104.dp
                                },
                            bottom = 18.dp
                        ),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Surface(
                    modifier =
                        Modifier.size(
                            if (fontScale >= 1.25f) {
                                66.dp
                            } else {
                                78.dp
                            }
                        ),
                    shape = CircleShape,
                    color = Color(0xFF07110D),
                    border =
                        BorderStroke(
                            3.dp,
                            MainScoreGold
                        )
                ) {
                    Box(
                        contentAlignment = Alignment.Center
                    ) {
                        Text(
                            text = playerSuit(leader.id),
                            color =
                                if (
                                    leader.id == "rybka" ||
                                    leader.id == "masha"
                                ) {
                                    Color(0xFFC5453D)
                                } else {
                                    Color(0xFF656966)
                                },
                            fontSize =
                                if (fontScale >= 1.25f) {
                                    34.sp
                                } else {
                                    41.sp
                                },
                            fontWeight = FontWeight.Black
                        )
                    }
                }

                Spacer(modifier = Modifier.size(12.dp))

                Column(
                    modifier = Modifier.weight(1f)
                ) {
                    Text(
                        text =
                            if (leaderCount > 1) {
                                "👑  ОДИН ИЗ ЛИДЕРОВ"
                            } else {
                                "👑  ЛИДЕР"
                            },
                        color = MainScoreGold,
                        fontSize = 13.sp,
                        lineHeight = 17.sp,
                        fontWeight = FontWeight.Bold,
                        maxLines = 2,
                        softWrap = true,
                        overflow = TextOverflow.Ellipsis
                    )

                    Spacer(modifier = Modifier.height(2.dp))

                    Text(
                        text = "меньше поражений — лучше",
                        color = MainScoreMuted,
                        fontSize = 10.sp,
                        lineHeight = 13.sp,
                        maxLines = 3,
                        softWrap = true,
                        overflow = TextOverflow.Ellipsis
                    )

                    Spacer(modifier = Modifier.height(7.dp))

                    Text(
                        text = leader.name,
                        color = PokerPalette.TextPrimary,
                        fontSize =
                            if (fontScale >= 1.25f) {
                                21.sp
                            } else {
                                25.sp
                            },
                        lineHeight = 27.sp,
                        fontWeight = FontWeight.Black,
                        maxLines = 2,
                        softWrap = true,
                        overflow = TextOverflow.Ellipsis
                    )

                    Spacer(modifier = Modifier.height(2.dp))

                    Row(
                        verticalAlignment = Alignment.Bottom
                    ) {
                        Text(
                            text = losses.toString(),
                            color = MainScoreGreen,
                            fontSize =
                                if (fontScale >= 1.25f) {
                                    36.sp
                                } else {
                                    43.sp
                                },
                            fontWeight = FontWeight.Black
                        )

                        Spacer(modifier = Modifier.size(6.dp))

                        Text(
                            text = lossesWord(losses),
                            color = MainScoreMuted,
                            fontSize = 12.sp,
                            lineHeight = 15.sp,
                            maxLines = 2,
                            softWrap = true,
                            overflow = TextOverflow.Ellipsis,
                            modifier = Modifier.padding(bottom = 7.dp)
                        )
                    }
                }
            }
        }
    }
}

@Composable
private fun MiniStatCard(
    modifier: Modifier,
    iconRes: Int,
    title: String,
    value: String
) {
    val fontScale = LocalDensity.current.fontScale

    Surface(
        modifier =
            modifier.heightIn(
                min =
                    if (fontScale >= 1.25f) {
                        142.dp
                    } else {
                        118.dp
                    }
            ),
        color = MainScoreCard,
        border =
            BorderStroke(
                1.dp,
                MainScoreBorder
            ),
        shape = RoundedCornerShape(20.dp)
    ) {
        Row(
            modifier =
                Modifier
                    .fillMaxWidth()
                    .padding(
                        horizontal = 12.dp,
                        vertical = 13.dp
                    ),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Surface(
                modifier = Modifier.size(42.dp),
                color = Color(0xFF040D09),
                shape = RoundedCornerShape(12.dp)
            ) {
                Image(
                    painter = painterResource(id = iconRes),
                    contentDescription = null,
                    contentScale = ContentScale.Fit,
                    modifier = Modifier.padding(3.dp)
                )
            }

            Spacer(modifier = Modifier.size(9.dp))

            Column(
                modifier = Modifier.weight(1f)
            ) {
                Text(
                    text = title,
                    color = MainScoreMuted,
                    fontSize = 10.sp,
                    fontWeight = FontWeight.Medium,
                    lineHeight = 13.sp,
                    maxLines = 5,
                    softWrap = true,
                    overflow = TextOverflow.Ellipsis
                )

                Spacer(modifier = Modifier.height(5.dp))

                Text(
                    text = value,
                    color = PokerPalette.TextPrimary,
                    fontSize =
                        if (fontScale >= 1.25f) {
                            24.sp
                        } else {
                            27.sp
                        },
                    fontWeight = FontWeight.Black,
                    maxLines = 2,
                    softWrap = true
                )
            }
        }
    }
}

@Composable
private fun RankingCard(
    players: List<MainScorePlayer>,
    canEdit: Boolean,
    onEdit: (MainScorePlayer) -> Unit
) {

    Surface(
        modifier =
            Modifier.fillMaxWidth(),
        color =
            MainScoreCard,
        border =
            BorderStroke(
                1.dp,
                MainScoreBorder
            ),
        shape =
            RoundedCornerShape(
                22.dp
            )
    ) {

        Column(
            modifier =
                Modifier.padding(
                    horizontal =
                        16.dp,
                    vertical =
                        10.dp
                )
        ) {

            players.forEachIndexed {
                    index,
                    player ->

                val value =
                    player.losses
                        ?: 0

                Row(
                    modifier =
                        Modifier
                            .fillMaxWidth()
                            .clickable(
                                enabled =
                                    canEdit &&
                                        player.losses !=
                                        null
                            ) {
                                onEdit(
                                    player
                                )
                            }
                            .padding(
                                vertical =
                                    13.dp
                            ),
                    verticalAlignment =
                        Alignment.CenterVertically
                ) {

                    Text(
                        text =
                            when (
                                index
                            ) {
                                0 -> "🥇"
                                1 -> "🥈"
                                2 -> "🥉"
                                else -> "4"
                            },
                        color =
                            MainScoreMuted,
                        fontSize =
                            if (
                                index <
                                3
                            ) {
                                25.sp
                            } else {
                                21.sp
                            },
                        modifier =
                            Modifier
                                .size(
                                    42.dp
                                )
                                .padding(
                                    top =
                                        4.dp
                                )
                    )

                    Surface(
                        modifier =
                            Modifier.size(
                                43.dp
                            ),
                        shape =
                            CircleShape,
                        color =
                            Color(
                                0xFF132A20
                            ),
                        border =
                            BorderStroke(
                                1.dp,
                                if (
                                    index ==
                                    0
                                ) {
                                    MainScoreGold
                                } else {
                                    MainScoreBorder
                                }
                            )
                    ) {

                        Box(
                            contentAlignment =
                                Alignment.Center
                        ) {

                            Text(
                                text =
                                    playerSuit(
                                        player.id
                                    ),
                                color =
                                    if (
                                        player.id ==
                                        "rybka" ||
                                        player.id ==
                                        "masha"
                                    ) {
                                        Color(
                                            0xFFC85850
                                        )
                                    } else {
                                        PokerPalette
                                            .TextPrimary
                                    },
                                fontSize =
                                    23.sp,
                                fontWeight =
                                    FontWeight.Bold
                            )
                        }
                    }

                    Spacer(
                        modifier =
                            Modifier.size(
                                12.dp
                            )
                    )

                    Column(
                        modifier =
                            Modifier.weight(
                                1f
                            )
                    ) {

                        Text(
                            text =
                                player.name,
                            color =
                                PokerPalette.TextPrimary,
                            fontSize =
                                18.sp,
                            fontWeight =
                                FontWeight.Bold
                        )

                        if (
                            canEdit
                        ) {

                            Text(
                                text =
                                    "нажми для корректировки",
                                color =
                                    MainScoreMuted,
                                fontSize =
                                    10.sp
                            )
                        }
                    }

                    Text(
                        text =
                            value.toString(),
                        color =
                            if (
                                index ==
                                0
                            ) {
                                MainScoreGreen
                            } else {
                                MainScoreRed
                            },
                        fontSize =
                            31.sp,
                        fontWeight =
                            FontWeight.Black
                    )
                }

                if (
                    index !=
                    players.lastIndex
                ) {

                    Surface(
                        modifier =
                            Modifier
                                .fillMaxWidth()
                                .height(
                                    1.dp
                                ),
                        color =
                            Color(
                                0xFF2B3B32
                            )
                    ) {}
                }
            }
        }
    }
}

@Composable
private fun HistoryCard(
    records: List<MainScoreRecord>
) {

    Surface(
        modifier =
            Modifier.fillMaxWidth(),
        color =
            MainScoreCard,
        border =
            BorderStroke(
                1.dp,
                MainScoreBorder
            ),
        shape =
            RoundedCornerShape(
                22.dp
            )
    ) {

        Column(
            modifier =
                Modifier.padding(
                    17.dp
                )
        ) {

            Text(
                text =
                    "ВСЯ ИСТОРИЯ",
                color =
                    MainScoreGold,
                fontSize =
                    18.sp,
                fontWeight =
                    FontWeight.Bold
            )

            Spacer(
                modifier =
                    Modifier.height(
                        9.dp
                    )
            )

            if (
                records.isEmpty()
            ) {

                Text(
                    text =
                        "Пока недостаточно данных для рекордов.",
                    color =
                        MainScoreMuted,
                    fontSize =
                        14.sp
                )

            } else {

                records.forEachIndexed {
                        index,
                        record ->

                    Row(
                        modifier =
                            Modifier
                                .fillMaxWidth()
                                .padding(
                                    vertical =
                                        10.dp
                                ),
                        verticalAlignment =
                            Alignment.CenterVertically
                    ) {

                        Image(
                            painter =
                                painterResource(
                                    id =
                                        record.iconRes
                                ),
                            contentDescription =
                                null,
                            modifier =
                                Modifier.size(
                                    46.dp
                                )
                        )

                        Spacer(
                            modifier =
                                Modifier.size(
                                    11.dp
                                )
                        )

                        Column(
                            modifier =
                                Modifier.weight(
                                    1f
                                )
                        ) {

                            Text(
                                text =
                                    record.title,
                                color =
                                    PokerPalette.TextPrimary,
                                fontSize =
                                    15.sp,
                                fontWeight =
                                    FontWeight.Medium
                            )

                            Spacer(
                                modifier =
                                    Modifier.height(
                                        3.dp
                                    )
                            )

                            Text(
                                text =
                                    record.playerName,
                                color =
                                    MainScoreGold,
                                fontSize =
                                    14.sp,
                                fontWeight =
                                    FontWeight.Bold
                            )
                        }

                        Text(
                            text =
                                record.value,
                            color =
                                if (
                                    record.title.contains(
                                        "Больше всего"
                                    ) ||
                                    record.title.contains(
                                        "серия"
                                    )
                                ) {
                                    MainScoreRed
                                } else {
                                    MainScoreGreen
                                },
                            fontSize =
                                18.sp,
                            fontWeight =
                                FontWeight.Black
                        )
                    }

                    if (
                        index !=
                        records.lastIndex
                    ) {

                        Surface(
                            modifier =
                                Modifier
                                    .fillMaxWidth()
                                    .height(
                                        1.dp
                                    ),
                            color =
                                Color(
                                    0xFF2B3B32
                                )
                        ) {}
                    }
                }
            }

            if (
                records.any {
                    it.title.contains(
                        "серия",
                        ignoreCase =
                            true
                    )
                }
            ) {

                Spacer(
                    modifier =
                        Modifier.height(
                            8.dp
                        )
                )

                Text(
                    text =
                        "Подробные серии считаются по классическим партиям, сыгранным уже через Дуракометр.",
                    color =
                        MainScoreMuted,
                    fontSize =
                        11.sp
                )
            }
        }
    }
}
