/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package com.runicgateway.app.ui.shard

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.runicgateway.app.R
import com.runicgateway.app.data.api.dto.ChampDto
import com.runicgateway.app.ui.components.PillTone
import com.runicgateway.app.ui.components.ShardCard
import com.runicgateway.app.ui.components.StatusPill

/** The champion-spawn board (PLAN.md §6.2), live via SSE deltas. */
@Composable
fun ChampsScreen(
    modifier: Modifier = Modifier,
    viewModel: ChampsViewModel = hiltViewModel(),
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    val connected by viewModel.connected.collectAsStateWithLifecycle()

    LiveBoardScreen(
        emptyMessage = stringResource(R.string.champs_empty),
        state = state,
        connected = connected,
        onRetry = viewModel::load,
        key = { it.serial },
        modifier = modifier,
    ) { champ -> ChampCard(champ) }
}

@Composable
private fun ChampCard(champ: ChampDto) {
    ShardCard(Modifier.fillMaxWidth()) {
        Column(Modifier.padding(16.dp)) {
            Row(Modifier.fillMaxWidth()) {
                Text(
                    text = champ.name ?: champ.type ?: stringResource(R.string.champs_fallback_name),
                    style = MaterialTheme.typography.titleMedium,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                    modifier = Modifier.weight(1f),
                )
                champ.status?.let {
                    StatusPill(text = it, tone = champStatusTone(it))
                }
            }
            val detail = champDetail(champ)
            if (detail.isNotBlank()) {
                Text(
                    text = detail,
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    modifier = Modifier.padding(top = 6.dp),
                )
            }
            val where = listOfNotNull(champ.map, champ.x?.let { "(${champ.x}, ${champ.y})" }).joinToString(" ")
            if (where.isNotBlank()) {
                Text(
                    text = where,
                    style = MaterialTheme.typography.labelSmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                    modifier = Modifier.padding(top = 4.dp),
                )
            }
        }
    }
}

/** Map a champ status to a pill tone: live spawns read green, cooldowns amber. */
private fun champStatusTone(status: String): PillTone = when (status.lowercase()) {
    "active", "up", "spawned" -> PillTone.Success
    "cooldown", "restarting", "advancing" -> PillTone.Warning
    else -> PillTone.Neutral
}

/** A short category-specific status line, mirroring the website's champ detail. */
@Composable
private fun champDetail(champ: ChampDto): String = when (champ.category) {
    "sea" -> if (champ.hitsMax != null) {
        "%,d / %,d hp".format(champ.hits ?: 0, champ.hitsMax)
    } else {
        champ.boss ?: champ.type ?: ""
    }
    "mini" -> stringResource(R.string.champ_level, champ.level ?: 0)
    else -> when (champ.status) {
        "active" -> if (champ.maxKills != null) {
            "%,d / %,d kills".format(champ.kills ?: 0, champ.maxKills)
        } else {
            stringResource(R.string.champ_level, champ.level ?: 0)
        }
        "cooldown" -> stringResource(R.string.champ_cooldown)
        else -> ""
    }
}
