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

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.runicgateway.app.R
import com.runicgateway.app.ui.UiState
import com.runicgateway.app.ui.components.EmptyView
import com.runicgateway.app.ui.components.ErrorView
import com.runicgateway.app.ui.components.LoadingView
import com.runicgateway.app.ui.theme.ShardSuccess
import com.runicgateway.app.ui.theme.ShardSuccessDot

/**
 * A small "Live / Offline" indicator for the shard screens (PLAN.md §6.2): a dot +
 * label reflecting the SSE connection state. Green when connected, muted otherwise.
 */
@Composable
fun LiveChip(connected: Boolean, modifier: Modifier = Modifier) {
    val dotColor = if (connected) ShardSuccessDot else MaterialTheme.colorScheme.onSurfaceVariant
    val textColor = if (connected) ShardSuccess else MaterialTheme.colorScheme.onSurfaceVariant
    Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
        androidx.compose.foundation.layout.Box(
            Modifier
                .size(8.dp)
                .clip(CircleShape)
                .background(dotColor),
        )
        Text(
            text = stringResource(if (connected) R.string.shard_live else R.string.shard_offline),
            style = MaterialTheme.typography.labelMedium,
            color = textColor,
            modifier = Modifier.padding(start = 6.dp),
        )
    }
}

/**
 * The shared scaffold for a live shard board (champs/guilds/houses): a [LiveChip]
 * header over the board list, folding [state] into loading/error/empty/content
 * (§7). Each caller supplies the per-row composable. Governors use their own layout
 * (expandable history), so they don't route through this.
 */
@Composable
fun <T> LiveBoardScreen(
    emptyMessage: String,
    state: UiState<List<T>>,
    connected: Boolean,
    onRetry: () -> Unit,
    key: (T) -> Any,
    modifier: Modifier = Modifier,
    row: @Composable (T) -> Unit,
) {
    Column(modifier = modifier.fillMaxSize()) {
        Row(
            Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 10.dp),
            horizontalArrangement = Arrangement.End,
        ) {
            LiveChip(connected)
        }
        when (state) {
            is UiState.Loading -> LoadingView()
            is UiState.Error -> ErrorView(state.kind, onRetry = onRetry)
            is UiState.Success -> {
                if (state.data.isEmpty()) {
                    EmptyView(emptyMessage)
                } else {
                    LazyColumn(
                        modifier = Modifier.fillMaxSize().padding(horizontal = 16.dp),
                        verticalArrangement = Arrangement.spacedBy(8.dp),
                        contentPadding = androidx.compose.foundation.layout.PaddingValues(bottom = 16.dp),
                    ) {
                        items(state.data, key = key) { item -> row(item) }
                    }
                }
            }
        }
    }
}
