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

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
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.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.runicgateway.app.R
import com.runicgateway.app.ui.ErrorKind

/** Centered progress indicator for a whole-screen loading state (§7). */
@Composable
fun LoadingView(modifier: Modifier = Modifier) {
    Column(
        modifier = modifier.fillMaxSize().padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
    ) {
        CircularProgressIndicator()
    }
}

/**
 * Whole-screen error state with a friendly, kind-specific message and a Retry
 * button (§7). Copy is resolved from string resources so it stays localizable.
 *
 * [ErrorKind.FEATURE_UNAVAILABLE] renders **without** the button: an admin decides
 * whether the shard publishes that surface, so retrying cannot change the answer and
 * offering it would read as a transient failure the user could wait out (M11).
 */
@Composable
fun ErrorView(
    kind: ErrorKind,
    onRetry: () -> Unit,
    modifier: Modifier = Modifier,
) {
    Column(
        modifier = modifier.fillMaxSize().padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
    ) {
        Text(
            text = stringResource(errorMessageRes(kind)),
            style = MaterialTheme.typography.bodyLarge,
            textAlign = TextAlign.Center,
        )
        if (isRetryable(kind)) {
            Button(
                onClick = onRetry,
                modifier = Modifier.padding(top = 16.dp).width(160.dp),
            ) {
                Text(stringResource(R.string.action_retry))
            }
        }
    }
}

/** Whether retrying this failure could plausibly succeed. Pure, so it is unit-tested. */
fun isRetryable(kind: ErrorKind): Boolean = kind != ErrorKind.FEATURE_UNAVAILABLE

/** Centered informational message for an empty list (§7). */
@Composable
fun EmptyView(message: String, modifier: Modifier = Modifier) {
    Column(
        modifier = modifier.fillMaxSize().padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
    ) {
        Text(
            text = message,
            style = MaterialTheme.typography.bodyLarge,
            textAlign = TextAlign.Center,
        )
    }
}

private fun errorMessageRes(kind: ErrorKind): Int = when (kind) {
    ErrorKind.NETWORK -> R.string.error_network
    ErrorKind.NOT_FOUND -> R.string.error_not_found
    ErrorKind.RATE_LIMITED -> R.string.error_rate_limited
    ErrorKind.SHARD_OFFLINE -> R.string.error_shard_offline
    ErrorKind.FEATURE_UNAVAILABLE -> R.string.error_feature_unavailable
    ErrorKind.SERVER -> R.string.error_server
}
