package ru.durakscore.app

import androidx.compose.ui.res.painterResource
import androidx.compose.ui.layout.ContentScale
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Card
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.Box
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.material3.Checkbox
import androidx.compose.material3.CheckboxDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults
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.platform.LocalDensity
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

enum class GameType {
    CLASSIC,
    CUSTOM
}

data class GamePlayer(
    val id: String,
    val name: String,
    val gender: String,
    val isCore: Boolean,
    val isGuest: Boolean = false,
    val sortOrder: Int = 999
)

data class GameSetup(
    val type: GameType,
    val players: List<GamePlayer>,
    val targetScore: Int
)

@Composable
fun NewGameSetupScreen(
    onBack: () -> Unit,
    onStartGame: (GameSetup) -> Unit
) {
    var permanentPlayers by remember {
        mutableStateOf<List<GamePlayer>>(emptyList())
    }

    var isLoading by remember { mutableStateOf(true) }
    var loadError by remember { mutableStateOf<String?>(null) }

    var selectedType by remember {
        mutableStateOf<GameType?>(null)
    }

    var selectedPlayerIds by remember {
        mutableStateOf<Set<String>>(emptySet())
    }

    var guestPlayers by remember {
        mutableStateOf<List<GamePlayer>>(emptyList())
    }

    var guestName by remember { mutableStateOf("") }
    var guestGender by remember { mutableStateOf("male") }

    var targetScoreText by remember { mutableStateOf("15") }

    LaunchedEffect(Unit) {

        val user =
            DurakAuthSession.current()

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

            isLoading =
                false

            return@LaunchedEffect
        }

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

                    permanentPlayers =
                        serverPlayers
                            .map {
                                    player ->

                                GamePlayer(
                                    id =
                                        player.id,
                                    name =
                                        player.name,
                                    gender =
                                        player.gender.ifBlank {
                                            "male"
                                        },
                                    isCore =
                                        player.isCore,
                                    isGuest =
                                        false,
                                    sortOrder =
                                        player.sortOrder
                                )
                            }
                            .sortedBy {
                                it.sortOrder
                            }

                    isLoading =
                        false

                    loadError =
                        null
                },
                onError = {
                        message ->

                    loadError =
                        message.ifBlank {
                            "Не удалось загрузить игроков"
                        }

                    isLoading =
                        false
                }
            )
    }

    val corePlayers = permanentPlayers.filter { it.isCore }
    val selectedPermanentPlayers =
        permanentPlayers.filter { it.id in selectedPlayerIds }

    val currentPlayers = when (selectedType) {
        GameType.CLASSIC -> corePlayers
        GameType.CUSTOM -> selectedPermanentPlayers + guestPlayers
        null -> emptyList()
    }

    val targetScore = targetScoreText.toIntOrNull()
    val targetValid = targetScore != null && targetScore in 2..99

    val canStart = when (selectedType) {
        GameType.CLASSIC -> corePlayers.size >= 4 && targetValid
        GameType.CUSTOM -> currentPlayers.size >= 2 && targetValid
        null -> false
    }

    PokerScreen {
        PokerBackTextButton(onClick = onBack)

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

        GothicNewGameHero()

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

        when {
            isLoading -> {
                PokerPanel {
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(14.dp)
                    ) {
                        CircularProgressIndicator(
                            color = PokerPalette.Gold
                        )
                        Text(
                            text = "Загружаю игроков...",
                            color = PokerPalette.TextPrimary,
                            fontSize = 17.sp
                        )
                    }
                }
            }

            loadError != null -> {
                PokerPanel {
                    Text(
                        text = loadError!!,
                        color = PokerPalette.Danger,
                        fontSize = 17.sp,
                        fontWeight = FontWeight.Bold
                    )
                }
            }

            else -> {
                PokerPanel {
                    Text(
                        text = "01  •  СОСТАВ ИГРЫ",
                        color = PokerPalette.CrimsonBright,
                        fontSize = 20.sp,
                        fontWeight = FontWeight.Bold
                    )

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

                    if (selectedType == GameType.CLASSIC) {
                        PokerPrimaryButton(
                            text = "♠  Классический набор игроков",
                            onClick = { selectedType = GameType.CLASSIC }
                        )
                    } else {
                        PokerSecondaryButton(
                            text = "♠  Классический набор игроков",
                            onClick = { selectedType = GameType.CLASSIC }
                        )
                    }

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

                    Text(
                        text = "Дмитрий, Денис, Рыбка и Маша",
                        color = PokerPalette.TextSecondary,
                        fontSize = 14.sp
                    )

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

                    if (selectedType == GameType.CUSTOM) {
                        PokerPrimaryButton(
                            text = "♣  Другой состав",
                            onClick = { selectedType = GameType.CUSTOM }
                        )
                    } else {
                        PokerSecondaryButton(
                            text = "♣  Другой состав",
                            onClick = { selectedType = GameType.CUSTOM }
                        )
                    }

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

                    Text(
                        text = "Выбрать игроков вручную или добавить гостя",
                        color = PokerPalette.TextSecondary,
                        fontSize = 14.sp
                    )
                }

                if (selectedType != null) {
                    Spacer(modifier = Modifier.height(16.dp))

                    PokerPanel {
                        Text(
                            text = "02  •  ДО СКОЛЬКИ ИГРАЕМ",
                            color = PokerPalette.CrimsonBright,
                            fontSize = 20.sp,
                            fontWeight = FontWeight.Bold
                        )

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

                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            Column(modifier = Modifier.weight(1f)) {
                                if (targetScoreText == "10") {
                                    PokerPrimaryButton(
                                        text = "До 10",
                                        onClick = { targetScoreText = "10" }
                                    )
                                } else {
                                    PokerSecondaryButton(
                                        text = "До 10",
                                        onClick = { targetScoreText = "10" }
                                    )
                                }
                            }

                            Column(modifier = Modifier.weight(1f)) {
                                if (targetScoreText == "15") {
                                    PokerPrimaryButton(
                                        text = "До 15",
                                        onClick = { targetScoreText = "15" }
                                    )
                                } else {
                                    PokerSecondaryButton(
                                        text = "До 15",
                                        onClick = { targetScoreText = "15" }
                                    )
                                }
                            }
                        }

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

                        OutlinedTextField(
                            value = targetScoreText,
                            onValueChange = { value ->
                                targetScoreText = value.filter { it.isDigit() }.take(2)
                            },
                            modifier = Modifier.fillMaxWidth(),
                            label = { Text("Свой лимит") },
                            supportingText = {
                                Text("Можно указать от 2 до 99")
                            },
                            singleLine = true,
                            keyboardOptions = KeyboardOptions(
                                keyboardType = KeyboardType.Number
                            ),
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = PokerPalette.TextPrimary,
                                unfocusedTextColor = PokerPalette.TextPrimary,
                                focusedBorderColor = PokerPalette.Gold,
                                unfocusedBorderColor = PokerPalette.GoldDark,
                                focusedLabelColor = PokerPalette.Gold,
                                unfocusedLabelColor = PokerPalette.TextSecondary,
                                focusedSupportingTextColor = PokerPalette.TextSecondary,
                                unfocusedSupportingTextColor = PokerPalette.TextSecondary,
                                cursorColor = PokerPalette.Gold
                            )
                        )
                    }
                }
                if (selectedType == GameType.CUSTOM) {
                    Spacer(modifier = Modifier.height(16.dp))

                    PokerPanel {
                        Text(
                            text = "03  •  ВЫБЕРИ ИГРОКОВ",
                            color = PokerPalette.CrimsonBright,
                            fontSize = 20.sp,
                            fontWeight = FontWeight.Bold
                        )

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

                        permanentPlayers.forEach { player ->
                            PlayerPreviewRow(
                                player = player,
                                checked = player.id in selectedPlayerIds,
                                enabled = true,
                                onToggle = {
                                    selectedPlayerIds =
                                        if (player.id in selectedPlayerIds) {
                                            selectedPlayerIds - player.id
                                        } else {
                                            selectedPlayerIds + player.id
                                        }
                                }
                            )
                        }
                    }

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

                    PokerPanel {
                        Text(
                            text = "☠  ДОБАВИТЬ ГОСТЯ",
                            color = PokerPalette.CrimsonBright,
                            fontSize = 20.sp,
                            fontWeight = FontWeight.Bold
                        )

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

                        OutlinedTextField(
                            value = guestName,
                            onValueChange = { guestName = it.take(30) },
                            modifier = Modifier.fillMaxWidth(),
                            label = { Text("Имя гостя") },
                            singleLine = true,
                            colors = OutlinedTextFieldDefaults.colors(
                                focusedTextColor = PokerPalette.TextPrimary,
                                unfocusedTextColor = PokerPalette.TextPrimary,
                                focusedBorderColor = PokerPalette.Gold,
                                unfocusedBorderColor = PokerPalette.GoldDark,
                                focusedLabelColor = PokerPalette.Gold,
                                unfocusedLabelColor = PokerPalette.TextSecondary,
                                cursorColor = PokerPalette.Gold
                            )
                        )

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

                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.spacedBy(10.dp)
                        ) {
                            Column(modifier = Modifier.weight(1f)) {
                                if (guestGender == "male") {
                                    PokerPrimaryButton(
                                        text = "Мужской",
                                        onClick = { guestGender = "male" }
                                    )
                                } else {
                                    PokerSecondaryButton(
                                        text = "Мужской",
                                        onClick = { guestGender = "male" }
                                    )
                                }
                            }

                            Column(modifier = Modifier.weight(1f)) {
                                if (guestGender == "female") {
                                    PokerPrimaryButton(
                                        text = "Женский",
                                        onClick = { guestGender = "female" }
                                    )
                                } else {
                                    PokerSecondaryButton(
                                        text = "Женский",
                                        onClick = { guestGender = "female" }
                                    )
                                }
                            }
                        }

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

                        PokerSecondaryButton(
                            text = "Добавить гостя",
                            enabled = guestName.trim().isNotEmpty(),
                            onClick = {
                                val cleanName = guestName.trim()
                                if (cleanName.isNotEmpty()) {
                                    guestPlayers = guestPlayers + GamePlayer(
                                        id = "guest_${System.currentTimeMillis()}_${guestPlayers.size}",
                                        name = cleanName,
                                        gender = guestGender,
                                        isCore = false,
                                        isGuest = true
                                    )
                                    guestName = ""
                                }
                            }
                        )

                        if (guestPlayers.isNotEmpty()) {
                            Spacer(modifier = Modifier.height(14.dp))

                            guestPlayers.forEach { guest ->
                                Row(
                                    modifier = Modifier
                                        .fillMaxWidth()
                                        .padding(vertical = 6.dp),
                                    verticalAlignment = Alignment.CenterVertically
                                ) {
                                    Column(modifier = Modifier.weight(1f)) {
                                        Text(
                                            text = guest.name,
                                            color = PokerPalette.TextPrimary,
                                            fontSize = 18.sp,
                                            fontWeight = FontWeight.Bold
                                        )
                                        Text(
                                            text = "Гость",
                                            color = PokerPalette.TextSecondary,
                                            fontSize = 13.sp
                                        )
                                    }

                                    TextButton(
                                        onClick = {
                                            guestPlayers = guestPlayers.filterNot {
                                                it.id == guest.id
                                            }
                                        }
                                    ) {
                                        Text(
                                            text = "Убрать",
                                            color = PokerPalette.Danger
                                        )
                                    }
                                }
                            }
                        }
                    }
                }

                if (selectedType != null) {
                    Spacer(modifier = Modifier.height(18.dp))

                    PokerPanel {
                        Text(
                            text = "За столом: ${currentPlayers.size}",
                            color = PokerPalette.TextSecondary,
                            fontSize = 15.sp
                        )

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

                        PokerPrimaryButton(
                            text = "РАЗДАТЬ КАРТЫ  •  ПОЕХАЛИ",
                            enabled = canStart,
                            onClick = {
                                val score = targetScore ?: return@PokerPrimaryButton
                                onStartGame(
                                    GameSetup(
                                        type = selectedType!!,
                                        players = currentPlayers,
                                        targetScore = score
                                    )
                                )
                            }
                        )

                        if (!canStart) {
                            Spacer(modifier = Modifier.height(8.dp))
                            Text(
                                text = when {
                                    !targetValid -> "Укажи корректный лимит счёта"
                                    selectedType == GameType.CLASSIC -> "Не удалось загрузить всю основную четвёрку"
                                    else -> "Выбери минимум двух игроков"
                                },
                                color = PokerPalette.TextSecondary,
                                fontSize = 13.sp
                            )
                        }
                    }
                }
            }
        }

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

@Composable
private fun GothicNewGameHero() {
    val fontScale = LocalDensity.current.fontScale
    val heroMinHeight =
        when {
            fontScale >= 1.30f -> 194.dp
            fontScale >= 1.15f -> 174.dp
            else -> 154.dp
        }

    Card(
        modifier =
            Modifier
                .fillMaxWidth()
                .heightIn(min = heroMinHeight),
        colors =
            CardDefaults.cardColors(
                containerColor = Color(0xF2080908)
            ),
        border =
            BorderStroke(
                1.dp,
                PokerPalette.GoldDark
            ),
        shape = RoundedCornerShape(18.dp)
    ) {
        Box(
            modifier =
                Modifier
                    .fillMaxWidth()
                    .heightIn(min = heroMinHeight)
        ) {
            Image(
                painter =
                    painterResource(
                        id = R.drawable.gothic_new_game_jester
                    ),
                contentDescription = null,
                contentScale = ContentScale.Fit,
                modifier =
                    Modifier
                        .align(Alignment.CenterEnd)
                        .fillMaxHeight()
                        .width(170.dp)
            )

            Box(
                modifier =
                    Modifier
                        .align(Alignment.CenterEnd)
                        .fillMaxHeight()
                        .width(195.dp)
                        .background(
                            brush =
                                androidx.compose.ui.graphics.Brush
                                    .horizontalGradient(
                                        listOf(
                                            Color(0xF2080908),
                                            Color(0xB0080908),
                                            Color.Transparent
                                        )
                                    )
                        )
            )

            Column(
                modifier =
                    Modifier
                        .fillMaxWidth()
                        .padding(
                            start = 16.dp,
                            top = 16.dp,
                            end =
                                if (fontScale >= 1.25f) {
                                    70.dp
                                } else {
                                    125.dp
                                },
                            bottom = 12.dp
                        )
            ) {
                Text(
                    text = "НОВАЯ ПАРТИЯ",
                    color = PokerPalette.TextPrimary,
                    fontFamily = PokerDisplayFont,
                    fontSize =
                        if (fontScale >= 1.25f) {
                            21.sp
                        } else {
                            24.sp
                        },
                    lineHeight = 27.sp,
                    fontWeight = FontWeight.Black,
                    maxLines = 2,
                    softWrap = true
                )

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

                Text(
                    text = "ВЫБЕРИ, КТО СЕГОДНЯ ПОСТРАДАЕТ",
                    color = PokerPalette.CrimsonBright,
                    fontSize = 10.sp,
                    lineHeight = 14.sp,
                    fontWeight = FontWeight.Black,
                    maxLines = 3,
                    softWrap = true
                )

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

                Text(
                    text = "Состав • лимит • карты на стол",
                    color = PokerPalette.Gold,
                    fontSize = 10.5.sp,
                    lineHeight = 14.sp,
                    maxLines = 3,
                    softWrap = true
                )
            }
        }
    }
}

@Composable
private fun PlayerPreviewRow(
    player: GamePlayer,
    checked: Boolean,
    enabled: Boolean,
    onToggle: () -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(enabled = enabled) { onToggle() }
            .padding(vertical = 7.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Checkbox(
            checked = checked,
            enabled = enabled,
            onCheckedChange = { onToggle() },
            colors = CheckboxDefaults.colors(
                checkedColor = PokerPalette.Crimson,
                checkmarkColor = PokerPalette.TextPrimary,
                uncheckedColor = PokerPalette.GoldDark,
                disabledCheckedColor = PokerPalette.GoldDark,
                disabledUncheckedColor = PokerPalette.Disabled
            )
        )

        Column(
            modifier = Modifier
                .weight(1f)
                .padding(start = 8.dp)
        ) {
            Text(
                text = player.name,
                color = PokerPalette.TextPrimary,
                fontSize = 18.sp,
                lineHeight = 22.sp,
                fontWeight = FontWeight.Bold,
                maxLines = 2,
                softWrap = true
            )

            Text(
                text = if (player.isGuest) "Гость" else if (player.isCore) "Основной игрок" else "Игрок",
                color = PokerPalette.TextSecondary,
                fontSize = 13.sp,
                lineHeight = 17.sp,
                maxLines = 2,
                softWrap = true
            )
        }

        Text(
            text = if (player.gender == "female") "♥" else "♠",
            color = if (player.gender == "female") PokerPalette.Danger else PokerPalette.Gold,
            fontSize = 20.sp,
            fontWeight = FontWeight.Bold
        )
    }
}
