package ru.durakscore.app

import androidx.activity.compose.BackHandler
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Brush
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.background
import androidx.compose.foundation.Image
import androidx.compose.foundation.BorderStroke
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.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.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
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.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import java.util.Date

private data class AchievementGame(
    val id: String,
    val targetScore: Int,
    val scores: Map<String, Int>,
    val history: List<String>,
    val loserId: String?,
    val finishedAt: Timestamp?
)

private data class PlayerAchievementStats(
    val gamesPlayed: Int,
    val losses: Int,
    val totalPoints: Int,
    val bestRoundStreak: Int,
    val maxLossStreak: Int,
    val cleanGames: Int,
    val nearEscapeGames: Int,
    val bestSurvivedScore: Int,
    val bestSurvivedTarget: Int
)

private data class AchievementItem(
    val icon: String,
    val title: String,
    val description: String,
    val unlocked: Boolean,
    val progress: String
)

private data class TableRecord(
    val icon: String,
    val title: String,
    val holder: String,
    val value: String
)

private val corePlayers =
    listOf(
        "dmitry" to "Дмитрий",
        "denis" to "Денис",
        "rybka" to "Рыбка",
        "masha" to "Маша"
    )

private fun parseAchievementGame(
    game: ServerFinishedGame
): AchievementGame? {

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

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

    return AchievementGame(
        id =
            game.id,
        targetScore =
            game.targetScore,
        scores =
            game.finalScores,
        history =
            game.history,
        loserId =
            game.loserId
                .takeIf {
                    it.isNotBlank()
                },
        finishedAt =
            game.finishedAtEpochMillis
                .takeIf {
                    it > 0L
                }
                ?.let {
                    Timestamp(
                        Date(
                            it
                        )
                    )
                }
    )
}

private fun bestNoPointStreak(
    game: AchievementGame,
    playerId: String
): Int {

    var current =
        0

    var best =
        0

    game.history.forEach {
            loserId ->

        if (
            loserId ==
            playerId
        ) {
            current =
                0
        } else {
            current++

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

    return best
}

private fun calculatePlayerStats(
    games: List<AchievementGame>,
    playerId: String
): PlayerAchievementStats {

    val playerGames =
        games
            .filter {
                it.scores
                    .containsKey(
                        playerId
                    )
            }
            .sortedBy {
                it.finishedAt
                    ?.seconds
                    ?: 0L
            }

    var currentLossStreak =
        0

    var maxLossStreak =
        0

    playerGames.forEach {
            game ->

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

            if (
                currentLossStreak >
                maxLossStreak
            ) {
                maxLossStreak =
                    currentLossStreak
            }
        } else {
            currentLossStreak =
                0
        }
    }

    var bestSurvivedScore =
        0

    var bestSurvivedTarget =
        0

    playerGames
        .filter {
            it.loserId !=
                playerId
        }
        .forEach {
                game ->

            val score =
                game.scores[playerId]
                    ?: 0

            val oldDistance =
                if (
                    bestSurvivedTarget >
                    0
                ) {
                    bestSurvivedTarget -
                            bestSurvivedScore
                } else {
                    Int.MAX_VALUE
                }

            val newDistance =
                game.targetScore -
                        score

            if (
                newDistance <
                oldDistance
            ) {
                bestSurvivedScore =
                    score

                bestSurvivedTarget =
                    game.targetScore
            }
        }

    return PlayerAchievementStats(
        gamesPlayed =
            playerGames.size,
        losses =
            playerGames.count {
                it.loserId ==
                    playerId
            },
        totalPoints =
            playerGames.sumOf {
                game ->
                game.history.count {
                    it ==
                        playerId
                }
            },
        bestRoundStreak =
            playerGames
                .maxOfOrNull {
                    bestNoPointStreak(
                        game =
                            it,
                        playerId =
                            playerId
                    )
                }
                ?: 0,
        maxLossStreak =
            maxLossStreak,
        cleanGames =
            playerGames.count {
                (it.scores[playerId] ?: 0) ==
                    0
            },
        nearEscapeGames =
            playerGames.count { game ->

                game.loserId !=
                    playerId &&
                    (
                        game.scores[playerId]
                            ?: 0
                        ) ==
                    game.targetScore - 1
            },
        bestSurvivedScore =
            bestSurvivedScore,
        bestSurvivedTarget =
            bestSurvivedTarget
    )
}

private fun buildAchievements(
    stats: PlayerAchievementStats
): List<AchievementItem> {

    val survivedOneAway =
        stats.bestSurvivedTarget >
            0 &&
            stats.bestSurvivedScore >=
            stats.bestSurvivedTarget - 1

    return listOf(
        AchievementItem(
            icon = "🧱",
            title = "Хуй пробьёшь",
            description =
                "Продержаться 10 раздач подряд без +1.",
            unlocked =
                stats.bestRoundStreak >=
                    10,
            progress =
                "${stats.bestRoundStreak}/10"
        ),

        AchievementItem(
            icon = "💩",
            title = "Серийный дурак",
            description =
                "Проиграть пять классических каток подряд.",
            unlocked =
                stats.maxLossStreak >=
                    5,
            progress =
                "${stats.maxLossStreak}/5 подряд"
        ),

        AchievementItem(
            icon = "🧲",
            title = "Ебаный пылесос +1",
            description =
                "Собрать 100 очков за всё время.",
            unlocked =
                stats.totalPoints >=
                    100,
            progress =
                "${stats.totalPoints}/100"
        ),

        AchievementItem(
            icon = "🪳",
            title = "Живучая тварь",
            description =
                "Оказаться в одном очке от проигрыша и всё-таки выжить.",
            unlocked =
                survivedOneAway,
            progress =
                if (
                    stats.bestSurvivedTarget >
                    0
                ) {
                    "${stats.bestSurvivedScore}/${stats.bestSurvivedTarget}"
                } else {
                    "—"
                }
        ),

        AchievementItem(
            icon = "🧼",
            title = "Сухой, аж бесит",
            description =
                "Трижды закончить катку вообще без +1.",
            unlocked =
                stats.cleanGames >=
                    3,
            progress =
                "${stats.cleanGames}/3"
        ),

        AchievementItem(
            icon = "☠️",
            title = "Смерть его не берёт",
            description =
                "Трижды закончить катку в одном очке от поражения и всё-таки не проиграть.",
            unlocked =
                stats.nearEscapeGames >=
                    3,
            progress =
                "${stats.nearEscapeGames}/3"
        ),

        AchievementItem(
            icon = "👑",
            title = "Заслуженный долбоёб",
            description =
                "Набрать 10 официальных поражений в приложении.",
            unlocked =
                stats.losses >=
                    10,
            progress =
                "${stats.losses}/10"
        )
    )
}

private fun buildRecords(
    games: List<AchievementGame>
): List<TableRecord> {

    if (
        games.isEmpty()
    ) {
        return emptyList()
    }

    val statsByPlayer =
        corePlayers.associate {
                (id, _) ->
            id to
                calculatePlayerStats(
                    games =
                        games,
                    playerId =
                        id
                )
        }

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

    val lossLeaders =
        if (
            maxLosses >
            0
        ) {
            statsByPlayer
                .filterValues {
                    it.losses ==
                        maxLosses
                }
                .keys
                .toList()
        } else {
            emptyList()
        }

    val longestStreak =
        statsByPlayer
            .maxByOrNull {
                it.value.bestRoundStreak
            }

    val mostClean =
        statsByPlayer
            .maxByOrNull {
                it.value.cleanGames
            }

    data class Escape(
        val playerId: String,
        val score: Int,
        val target: Int,
        val distance: Int
    )

    val closestEscape =
        games.flatMap {
                game ->

            corePlayers
                .mapNotNull {
                        (playerId, _) ->

                    if (
                        game.loserId ==
                        playerId ||
                        !game.scores
                            .containsKey(
                                playerId
                            )
                    ) {
                        null
                    } else {

                        val score =
                            game.scores[playerId]
                                ?: 0

                        Escape(
                            playerId =
                                playerId,
                            score =
                                score,
                            target =
                                game.targetScore,
                            distance =
                                game.targetScore -
                                    score
                        )
                    }
                }
        }
            .minByOrNull {
                it.distance
            }

    fun playerName(
        id: String?
    ): String =
        corePlayers
            .firstOrNull {
                it.first ==
                    id
            }
            ?.second
            ?: "—"

    val result =
        mutableListOf<TableRecord>()

    fun lossWord(
        value: Int
    ): String {

        val mod100 =
            value % 100

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

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

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

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

    if (
        lossLeaders.isNotEmpty()
    ) {

        val leaderNames =
            lossLeaders
                .map {
                    playerName(
                        it
                    )
                }
                .sorted()
                .joinToString(
                    separator = " и "
                )

        val title =
            when {
                maxLosses == 1 &&
                lossLeaders.size == 1 ->
                    "Пока главный дурак"

                maxLosses == 1 ->
                    "Пока главные дураки"

                lossLeaders.size > 1 ->
                    "Главные дураки"

                else ->
                    "Главный дурак"
            }

        val value =
            if (
                lossLeaders.size >
                1
            ) {
                "по $maxLosses ${lossWord(maxLosses)}"
            } else {
                "$maxLosses ${lossWord(maxLosses)}"
            }

        result.add(
            TableRecord(
                icon = "💩",
                title =
                    title,
                holder =
                    leaderNames,
                value =
                    value
            )
        )
    }

    if (
        longestStreak != null
    ) {
        result.add(
            TableRecord(
                icon = "🧱",
                title = "Железная жопа",
                holder =
                    playerName(
                        longestStreak.key
                    ),
                value =
                    "${longestStreak.value.bestRoundStreak} без +1"
            )
        )
    }

    if (
        mostClean != null
    ) {
        result.add(
            TableRecord(
                icon = "🧼",
                title = "Самый сухой",
                holder =
                    playerName(
                        mostClean.key
                    ),
                value =
                    "${mostClean.value.cleanGames} каток с нулём"
            )
        )
    }

    if (
        closestEscape != null
    ) {
        result.add(
            TableRecord(
                icon = "🪳",
                title = "Выжил на соплях",
                holder =
                    playerName(
                        closestEscape.playerId
                    ),
                value =
                    "${closestEscape.score}/${closestEscape.target}"
            )
        )
    }

    return result
}

private fun achievementIconRes(
    title: String
): Int =
    when (title) {
        "Хуй пробьёшь" ->
            R.drawable.gothic_spikes

        "Серийный дурак" ->
            R.drawable.gothic_serial_jester

        "Ебаный пылесос +1" ->
            R.drawable.gothic_vacuum

        "Живучая тварь" ->
            R.drawable.gothic_bandaged_heart

        "Сухой, аж бесит" ->
            R.drawable.gothic_goblet

        "Смерть его не берёт" ->
            R.drawable.gothic_burning_card

        "Заслуженный долбоёб" ->
            R.drawable.gothic_crown_skull

        else ->
            R.drawable.gothic_jester_face
    }

private fun recordIconRes(
    title: String
): Int =
    when {
        title.contains(
            "дурак",
            ignoreCase =
                true
        ) ->
            R.drawable.gothic_crown_skull

        title.contains(
            "Железная",
            ignoreCase =
                true
        ) ->
            R.drawable.gothic_armor

        title.contains(
            "сух",
            ignoreCase =
                true
        ) ->
            R.drawable.gothic_goblet

        title.contains(
            "сопл",
            ignoreCase =
                true
        ) ->
            R.drawable.gothic_bandaged_heart

        else ->
            R.drawable.gothic_skull_jester
    }

private fun achievementProgressFraction(
    title: String,
    stats: PlayerAchievementStats
): Float {

    val raw =
        when (title) {
            "Хуй пробьёшь" ->
                stats.bestRoundStreak / 10f

            "Серийный дурак" ->
                stats.maxLossStreak / 5f

            "Ебаный пылесос +1" ->
                stats.totalPoints / 100f

            "Живучая тварь" ->
                if (
                    stats.bestSurvivedTarget >
                    0 &&
                    stats.bestSurvivedScore >=
                    stats.bestSurvivedTarget - 1
                ) {
                    1f
                } else {
                    0f
                }

            "Сухой, аж бесит" ->
                stats.cleanGames / 3f

            "Смерть его не берёт" ->
                stats.nearEscapeGames / 3f

            "Заслуженный долбоёб" ->
                stats.losses / 10f

            else ->
                0f
        }

    return raw.coerceIn(
        0f,
        1f
    )
}

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

    BackHandler(
        onBack =
            onBack
    )

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

    var isLoading by remember {
        mutableStateOf(true)
    }

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

    var selectedPlayerId by remember(
        access.playerId
    ) {
        mutableStateOf(
            access.playerId
                .takeIf {
                    id ->
                    corePlayers.any {
                        it.first ==
                            id
                    }
                }
                ?: "denis"
        )
    }

    LaunchedEffect(Unit) {

        val user =
            DurakAuthSession.current()

        if (
            user ==
            null
        ) {
            isLoading =
                false

            errorText =
                "Пользователь не авторизован"

            return@LaunchedEffect
        }

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

                    games =
                        serverGames
                            .mapNotNull {
                                parseAchievementGame(
                                    it
                                )
                            }

                    isLoading =
                        false

                    errorText =
                        null
                },
                onError = {
                        message ->

                    isLoading =
                        false

                    errorText =
                        message.ifBlank {
                            "Не удалось загрузить достижения"
                        }
                }
            )
    }

    val selectedName =
        corePlayers
            .firstOrNull {
                it.first ==
                    selectedPlayerId
            }
            ?.second
            ?: selectedPlayerId

    val selectedStats =
        remember(
            games,
            selectedPlayerId
        ) {
            calculatePlayerStats(
                games =
                    games,
                playerId =
                    selectedPlayerId
            )
        }

    val achievements =
        remember(
            selectedStats
        ) {
            buildAchievements(
                selectedStats
            )
        }

    val records =
        remember(
            games
        ) {
            buildRecords(
                games
            )
        }

    PokerScreen {

        PokerBackTextButton(
            text =
                "← Назад",
            onClick =
                onBack
        )

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

        Text(
            text =
                "ДОСТИЖЕНИЯ",
            color =
                PokerPalette.TextPrimary,
            fontSize =
                31.sp,
            fontFamily =
                PokerDisplayFont,
            fontWeight =
                FontWeight.Black
        )

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

        AchievementHero()

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

        PlayerSelector(
            selectedPlayerId =
                selectedPlayerId,
            onSelect = {
                selectedPlayerId =
                    it
            }
        )

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

        when {

            isLoading -> {

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

                    CircularProgressIndicator(
                        color =
                            PokerPalette.CrimsonBright
                    )
                }
            }

            errorText != null -> {

                PokerPanel {

                    Text(
                        text =
                            errorText!!,
                        color =
                            PokerPalette.Danger
                    )
                }
            }

            else -> {

                GothicSectionTitle(
                    text =
                        "РЕКОРДЫ СТОЛА"
                )

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

                RecordsPanel(
                    records =
                        records
                )

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

                GothicSectionTitle(
                    text =
                        "ДОСТИЖЕНИЯ • $selectedName"
                )

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

                Text(
                    text =
                        "Открыто ${achievements.count { it.unlocked }} из ${achievements.size}",
                    color =
                        PokerPalette.TextSecondary,
                    fontSize =
                        12.sp
                )

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

                BoxWithConstraints(
                    modifier = Modifier.fillMaxWidth()
                ) {
                    val adaptiveSingleColumn =
                        maxWidth < 350.dp ||
                            LocalDensity.current.fontScale >= 1.25f

                    if (adaptiveSingleColumn) {
                        Column(
                            modifier = Modifier.fillMaxWidth(),
                            verticalArrangement =
                                Arrangement.spacedBy(9.dp)
                        ) {
                            achievements.forEach { item ->
                                AchievementGothicCard(
                                    achievement = item,
                                    progress =
                                        achievementProgressFraction(
                                            title = item.title,
                                            stats = selectedStats
                                        ),
                                    modifier = Modifier.fillMaxWidth()
                                )
                            }
                        }
                    } else {
                        Column(
                            modifier = Modifier.fillMaxWidth()
                        ) {
                            achievements
                                .chunked(2)
                                .forEach { rowItems ->
                                    Row(
                                        modifier = Modifier.fillMaxWidth(),
                                        horizontalArrangement =
                                            Arrangement.spacedBy(9.dp)
                                    ) {
                                        rowItems.forEach { item ->
                                            AchievementGothicCard(
                                                achievement = item,
                                                progress =
                                                    achievementProgressFraction(
                                                        title = item.title,
                                                        stats = selectedStats
                                                    ),
                                                modifier =
                                                    if (rowItems.size == 1) {
                                                        Modifier.fillMaxWidth()
                                                    } else {
                                                        Modifier.weight(1f)
                                                    }
                                            )
                                        }
                                    }

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

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

        PokerBottomBackButton(
            onClick =
                onBack
        )
    }
}

@Composable
private fun AchievementHero() {
    val fontScale = LocalDensity.current.fontScale
    val heroMinHeight =
        when {
            fontScale >= 1.30f -> 214.dp
            fontScale >= 1.15f -> 194.dp
            else -> 176.dp
        }
    val textEndPadding =
        if (fontScale >= 1.25f) {
            74.dp
        } else {
            140.dp
        }

    Surface(
        modifier =
            Modifier
                .fillMaxWidth()
                .heightIn(min = heroMinHeight),
        color = Color(0xF2070908),
        border =
            BorderStroke(
                1.dp,
                PokerPalette.GoldDark
            ),
        shape = RoundedCornerShape(18.dp)
    ) {
        Box(
            modifier =
                Modifier
                    .fillMaxWidth()
                    .heightIn(min = heroMinHeight)
        ) {
            Image(
                painter =
                    painterResource(
                        id = R.drawable.gothic_achievements_jester
                    ),
                contentDescription = null,
                contentScale = ContentScale.Fit,
                modifier =
                    Modifier
                        .align(Alignment.CenterEnd)
                        .fillMaxHeight()
                        .width(190.dp)
            )

            Box(
                modifier =
                    Modifier
                        .align(Alignment.CenterEnd)
                        .fillMaxHeight()
                        .width(220.dp)
                        .background(
                            brush =
                                Brush.horizontalGradient(
                                    colors =
                                        listOf(
                                            Color(0xF2070908),
                                            Color(0xB0070908),
                                            Color.Transparent
                                        )
                                )
                        )
            )

            Column(
                modifier =
                    Modifier
                        .fillMaxWidth()
                        .padding(
                            start = 17.dp,
                            top = 20.dp,
                            end = textEndPadding,
                            bottom = 16.dp
                        )
            ) {
                Text(
                    text = "ДУРАКОМЕТР",
                    color = PokerPalette.CrimsonBright,
                    fontSize =
                        if (fontScale >= 1.30f) {
                            18.sp
                        } else {
                            21.sp
                        },
                    lineHeight = 24.sp,
                    fontFamily = PokerDisplayFont,
                    fontWeight = FontWeight.Black,
                    maxLines = 2,
                    softWrap = true
                )

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

                Text(
                    text = "Слава, позор\nи сомнительные заслуги",
                    color = PokerPalette.Gold,
                    fontSize = 15.sp,
                    lineHeight = 20.sp,
                    fontWeight = FontWeight.SemiBold,
                    maxLines = 4,
                    softWrap = true
                )
            }
        }
    }
}

@Composable
private fun PlayerSelector(
    selectedPlayerId: String,
    onSelect: (String) -> Unit
) {

    Column(
        verticalArrangement =
            Arrangement.spacedBy(
                7.dp
            )
    ) {

        corePlayers
            .chunked(
                2
            )
            .forEach {
                    row ->

                Row(
                    modifier =
                        Modifier.fillMaxWidth(),
                    horizontalArrangement =
                        Arrangement.spacedBy(
                            7.dp
                        )
                ) {

                    row.forEach {
                            (id, name) ->

                        val selected =
                            id ==
                                selectedPlayerId

                        Surface(
                            modifier =
                                Modifier
                                    .weight(
                                        1f
                                    )
                                    .clickable {
                                        onSelect(
                                            id
                                        )
                                    },
                            color =
                                if (
                                    selected
                                ) {
                                    Color(
                                        0xFF260C0A
                                    )
                                } else {
                                    PokerPalette.Panel
                                },
                            border =
                                BorderStroke(
                                    if (
                                        selected
                                    ) {
                                        1.5.dp
                                    } else {
                                        1.dp
                                    },
                                    if (
                                        selected
                                    ) {
                                        PokerPalette.CrimsonBright
                                    } else {
                                        PokerPalette.GoldDark
                                    }
                                ),
                            shape =
                                RoundedCornerShape(
                                    14.dp
                                )
                        ) {

                            Text(
                                text =
                                    name,
                                modifier =
                                    Modifier.padding(
                                        horizontal =
                                            10.dp,
                                        vertical =
                                            9.dp
                                    ),
                                color =
                                    if (
                                        selected
                                    ) {
                                        PokerPalette.GoldBright
                                    } else {
                                        PokerPalette.TextPrimary
                                    },
                                fontSize =
                                    13.sp,
                                fontWeight =
                                    FontWeight.Bold
                            )
                        }
                    }
                }
            }
    }
}

@Composable
private fun GothicSectionTitle(
    text: String
) {

    Row(
        modifier =
            Modifier.fillMaxWidth(),
        verticalAlignment =
            Alignment.CenterVertically
    ) {

        Box(
            modifier =
                Modifier
                    .weight(
                        1f
                    )
                    .height(
                        1.dp
                    )
                    .background(
                        PokerPalette.GoldDark
                    )
        )

        Text(
            text =
                text,
            modifier =
                Modifier.padding(
                    horizontal =
                        10.dp
                ),
            color =
                PokerPalette.CrimsonBright,
            fontSize =
                14.sp,
            fontWeight =
                FontWeight.Black,
            letterSpacing =
                1.3.sp
        )

        Box(
            modifier =
                Modifier
                    .weight(
                        1f
                    )
                    .height(
                        1.dp
                    )
                    .background(
                        PokerPalette.GoldDark
                    )
        )
    }
}

@Composable
private fun RecordsPanel(
    records: List<TableRecord>
) {

    Surface(
        modifier =
            Modifier.fillMaxWidth(),
        color =
            Color(
                0xF2070B09
            ),
        border =
            BorderStroke(
                1.dp,
                PokerPalette.GoldDark
            ),
        shape =
            RoundedCornerShape(
                16.dp
            )
    ) {

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

            if (
                records.isEmpty()
            ) {

                Text(
                    text =
                        "Пока рекордов нет. Значит, ещё недостаточно натворили.",
                    color =
                        PokerPalette.TextSecondary,
                    fontSize =
                        13.sp
                )

            } else {

                records.forEachIndexed {
                        index,
                        record ->

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

                        Image(
                            painter =
                                painterResource(
                                    id =
                                        recordIconRes(
                                            record.title
                                        )
                                ),
                            contentDescription =
                                null,
                            modifier =
                                Modifier.size(
                                    50.dp
                                ),
                            contentScale =
                                ContentScale.Fit
                        )

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

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

                            Text(
                                text =
                                    record.title.uppercase(),
                                color =
                                    PokerPalette.TextPrimary,
                                fontSize =
                                    12.sp,
                                fontWeight =
                                    FontWeight.Black,
                                maxLines =
                                    2,
                                softWrap =
                                    true,
                                overflow =
                                    TextOverflow.Ellipsis
                            )

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

                            Text(
                                text =
                                    record.holder,
                                color =
                                    PokerPalette.CrimsonBright,
                                fontSize =
                                    12.sp,
                                fontWeight =
                                    FontWeight.SemiBold
                            )
                        }

                        Text(
                            text =
                                record.value,
                            color =
                                PokerPalette.GoldBright,
                            fontSize =
                                13.sp,
                            fontWeight =
                                FontWeight.Black
                        )
                    }

                    if (
                        index !=
                        records.lastIndex
                    ) {

                        Box(
                            modifier =
                                Modifier
                                    .fillMaxWidth()
                                    .height(
                                        1.dp
                                    )
                                    .background(
                                        Color(
                                            0xFF2A2419
                                        )
                                    )
                        )
                    }
                }
            }

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

            Text(
                text =
                    "Рекорды считаются по классическим партиям, записанным Дуракометром.",
                color =
                    PokerPalette.TextSecondary,
                fontSize =
                    10.sp
            )
        }
    }
}

@Composable
private fun AchievementGothicCard(
    achievement: AchievementItem,
    progress: Float,
    modifier: Modifier = Modifier
) {
    val fontScale = LocalDensity.current.fontScale

    val activeColor =
        if (achievement.unlocked) {
            PokerPalette.GoldBright
        } else {
            PokerPalette.CrimsonBright
        }

    val minimumHeight =
        when {
            fontScale >= 1.30f -> 246.dp
            fontScale >= 1.15f -> 214.dp
            else -> 184.dp
        }

    Surface(
        modifier =
            modifier.heightIn(
                min = minimumHeight
            ),
        color = Color(0xF2070B09),
        border =
            BorderStroke(
                1.dp,
                if (achievement.unlocked) {
                    PokerPalette.Gold
                } else {
                    PokerPalette.GoldDark
                }
            ),
        shape = RoundedCornerShape(15.dp)
    ) {
        Column(
            modifier =
                Modifier
                    .fillMaxWidth()
                    .padding(10.dp)
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Image(
                    painter =
                        painterResource(
                            id = achievementIconRes(achievement.title)
                        ),
                    contentDescription = null,
                    contentScale = ContentScale.Fit,
                    modifier =
                        Modifier.size(
                            if (fontScale >= 1.25f) {
                                48.dp
                            } else {
                                56.dp
                            }
                        )
                )

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

                Text(
                    text = achievement.title.uppercase(),
                    color =
                        if (achievement.unlocked) {
                            PokerPalette.GoldBright
                        } else {
                            PokerPalette.TextPrimary
                        },
                    fontSize = 11.sp,
                    lineHeight = 14.sp,
                    fontWeight = FontWeight.Black,
                    maxLines = 4,
                    softWrap = true,
                    overflow = TextOverflow.Ellipsis,
                    modifier = Modifier.weight(1f)
                )
            }

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

            Text(
                text = achievement.description,
                color = PokerPalette.TextSecondary,
                fontSize = 9.5.sp,
                lineHeight = 13.sp,
                maxLines = 6,
                softWrap = true,
                overflow = TextOverflow.Ellipsis
            )

            Spacer(modifier = Modifier.weight(1f))

            Box(
                modifier =
                    Modifier
                        .fillMaxWidth()
                        .height(5.dp)
                        .background(
                            Color(0xFF241D13),
                            RoundedCornerShape(100.dp)
                        )
            ) {
                Box(
                    modifier =
                        Modifier
                            .fillMaxWidth(progress)
                            .fillMaxHeight()
                            .background(
                                activeColor,
                                RoundedCornerShape(100.dp)
                            )
                )
            }

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

            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = achievement.progress,
                    color = PokerPalette.Gold,
                    fontSize = 10.sp,
                    fontWeight = FontWeight.Bold,
                    maxLines = 2
                )

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

                Text(
                    text =
                        if (achievement.unlocked) {
                            "✓ ОТКРЫТО"
                        } else {
                            "ЗАКРЫТО"
                        },
                    color = activeColor,
                    fontSize = 9.sp,
                    fontWeight = FontWeight.Black,
                    maxLines = 2
                )
            }
        }
    }
}

