package com.fabledsword.minstrel.admin.ui

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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.AssistChip
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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 androidx.navigation.NavHostController
import com.fabledsword.minstrel.models.RequestRef
import com.fabledsword.minstrel.nav.AdminRequests
import com.fabledsword.minstrel.shared.widgets.ShellContentWindowInsets
import com.fabledsword.minstrel.shared.widgets.EmptyState
import com.fabledsword.minstrel.shared.widgets.ErrorRetry
import com.fabledsword.minstrel.shared.widgets.LoadingCentered
import com.fabledsword.minstrel.shared.widgets.MinstrelTopAppBar
import com.fabledsword.minstrel.shared.widgets.PullToRefreshScaffold

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AdminRequestsScreen(
    navController: NavHostController,
    viewModel: AdminRequestsViewModel = hiltViewModel(),
) {
    val state by viewModel.uiState.collectAsStateWithLifecycle()
    Scaffold(
        contentWindowInsets = ShellContentWindowInsets,
        modifier = Modifier.fillMaxSize(),
        topBar = {
            MinstrelTopAppBar(
                title = "Admin · Requests",
                navController = navController,
                currentRouteName = AdminRequests::class.qualifiedName,
                onBack = { navController.popBackStack() },
            )
        },
    ) { inner ->
        PullToRefreshScaffold(
            onRefresh = { viewModel.refresh().join() },
            modifier = Modifier.fillMaxSize().padding(inner),
        ) {
            when (val s = state) {
                AdminRequestsUiState.Loading -> LoadingCentered()
                AdminRequestsUiState.Empty -> EmptyState(
                    title = "No requests waiting",
                    body = "When users ask Lidarr for new music, their pending " +
                        "requests show up here for approval.",
                )
                is AdminRequestsUiState.Error -> ErrorRetry(
                    title = "Couldn't load requests",
                    message = s.message,
                    onRetry = { viewModel.refresh() },
                )
                is AdminRequestsUiState.Success -> RequestList(
                    rows = s.rows,
                    usernames = s.usernames,
                    onApprove = viewModel::approve,
                    onReject = viewModel::reject,
                )
            }
        }
    }
}

@Composable
private fun RequestList(
    rows: List<RequestRef>,
    usernames: Map<String, String>,
    onApprove: (String) -> Unit,
    onReject: (String) -> Unit,
) {
    LazyColumn(modifier = Modifier.fillMaxSize()) {
        items(items = rows, key = { it.id }) { req ->
            AdminRequestRow(
                req = req,
                requester = usernames[req.userId]
                    ?: req.userId.takeIf { it.isNotEmpty() }?.take(USER_ID_PREFIX_LEN)
                    ?: "unknown",
                onApprove = { onApprove(req.id) },
                onReject = { onReject(req.id) },
            )
            HorizontalDivider()
        }
    }
}

@Composable
private fun AdminRequestRow(
    req: RequestRef,
    requester: String,
    onApprove: () -> Unit,
    onReject: () -> Unit,
) {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 12.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        Text(
            text = req.displayName,
            style = MaterialTheme.typography.bodyLarge,
            color = MaterialTheme.colorScheme.onSurface,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
        )
        Text(
            text = "Requested by $requester",
            style = MaterialTheme.typography.bodySmall,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
        )
        Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) {
            AssistChip(
                onClick = {},
                enabled = false,
                label = { Text(req.kind, style = MaterialTheme.typography.labelSmall) },
            )
            AssistChip(
                onClick = {},
                enabled = false,
                label = { Text(req.status.wire, style = MaterialTheme.typography.labelSmall) },
            )
        }
        if (req.artistName.isNotEmpty() && req.artistName != req.displayName) {
            Text(
                text = "Artist: ${req.artistName}",
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
            )
        }
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.End),
        ) {
            OutlinedButton(onClick = onReject) { Text("Reject") }
            Button(onClick = onApprove) { Text("Approve") }
        }
    }
}

// UUID prefix length used as a friendlier-than-raw-UUID fallback when
// the admin users list fetch fails and we can't resolve userId → name.
private const val USER_ID_PREFIX_LEN = 8
