package com.fabledsword.minstrel.admin.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
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.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
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.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController
import com.composables.icons.lucide.Inbox
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Music
import com.composables.icons.lucide.TriangleAlert
import com.composables.icons.lucide.Users
import com.fabledsword.minstrel.admin.data.AdminQuarantineRepository
import com.fabledsword.minstrel.admin.data.AdminRequestsRepository
import com.fabledsword.minstrel.admin.data.AdminTagSourcesRepository
import com.fabledsword.minstrel.admin.data.AdminUsersRepository
import com.fabledsword.minstrel.api.ErrorCopy
import com.fabledsword.minstrel.nav.Admin
import com.fabledsword.minstrel.nav.AdminQuarantine
import com.fabledsword.minstrel.nav.AdminRequests
import com.fabledsword.minstrel.nav.AdminTagSources
import com.fabledsword.minstrel.nav.AdminUsers
import com.fabledsword.minstrel.shared.widgets.ShellContentWindowInsets
import com.fabledsword.minstrel.shared.widgets.EmptyState
import com.fabledsword.minstrel.shared.widgets.LoadingCentered
import com.fabledsword.minstrel.shared.widgets.MinstrelTopAppBar
import com.fabledsword.minstrel.shared.widgets.PullToRefreshScaffold
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

// ─── State ───────────────────────────────────────────────────────────

data class AdminCounts(val requests: Int, val quarantine: Int, val users: Int, val tagSources: Int)

sealed interface AdminLandingUiState {
    data object Loading : AdminLandingUiState
    data class Success(val counts: AdminCounts) : AdminLandingUiState
    data class Error(val message: String) : AdminLandingUiState
}

// ─── ViewModel ───────────────────────────────────────────────────────

@HiltViewModel
class AdminLandingViewModel @Inject constructor(
    private val requestsRepo: AdminRequestsRepository,
    private val quarantineRepo: AdminQuarantineRepository,
    private val usersRepo: AdminUsersRepository,
    private val tagSourcesRepo: AdminTagSourcesRepository,
) : ViewModel() {

    private val internal = MutableStateFlow<AdminLandingUiState>(AdminLandingUiState.Loading)
    val uiState: StateFlow<AdminLandingUiState> = internal.asStateFlow()

    init {
        refresh()
    }

    fun refresh(): Job = viewModelScope.launch {
        internal.value = AdminLandingUiState.Loading
        try {
            val counts = coroutineScope {
                val req = async { requestsRepo.list().size }
                val qua = async { quarantineRepo.list().size }
                val usr = async { usersRepo.list().size }
                val tag = async { tagSourcesRepo.list().count { it.enabled } }
                AdminCounts(req.await(), qua.await(), usr.await(), tag.await())
            }
            internal.value = AdminLandingUiState.Success(counts)
        } catch (
            @Suppress("TooGenericExceptionCaught") e: Throwable,
        ) {
            internal.value = AdminLandingUiState.Error(
                ErrorCopy.fromThrowable(e),
            )
        }
    }
}

// ─── Screen ──────────────────────────────────────────────────────────

@Composable
fun AdminLandingScreen(
    navController: NavHostController,
    viewModel: AdminLandingViewModel = hiltViewModel(),
) {
    val state by viewModel.uiState.collectAsStateWithLifecycle()
    Scaffold(
        contentWindowInsets = ShellContentWindowInsets,
        modifier = Modifier.fillMaxSize(),
        topBar = {
            MinstrelTopAppBar(
                title = "Admin",
                navController = navController,
                currentRouteName = Admin::class.qualifiedName,
                onBack = { navController.popBackStack() },
            )
        },
    ) { inner ->
        PullToRefreshScaffold(
            onRefresh = { viewModel.refresh().join() },
            modifier = Modifier.fillMaxSize().padding(inner),
        ) {
            when (val s = state) {
                AdminLandingUiState.Loading -> LoadingCentered()
                is AdminLandingUiState.Error -> EmptyState(
                    title = "Couldn't load admin counts",
                    body = s.message,
                )
                is AdminLandingUiState.Success -> SectionList(
                    counts = s.counts,
                    navController = navController,
                )
            }
        }
    }
}

@Composable
private fun SectionList(counts: AdminCounts, navController: NavHostController) {
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        item {
            SectionCard(
                icon = Lucide.Inbox,
                title = "Requests",
                subtitle = "Approve or reject Lidarr requests",
                count = counts.requests,
                onClick = { navController.navigate(AdminRequests) },
            )
        }
        item {
            SectionCard(
                icon = Lucide.TriangleAlert,
                title = "Quarantine",
                subtitle = "Resolve scan failures",
                count = counts.quarantine,
                onClick = { navController.navigate(AdminQuarantine) },
            )
        }
        item {
            SectionCard(
                icon = Lucide.Users,
                title = "Users",
                subtitle = "Manage accounts and invites",
                count = counts.users,
                onClick = { navController.navigate(AdminUsers) },
            )
        }
        item {
            SectionCard(
                icon = Lucide.Music,
                title = "Tag sources",
                subtitle = "Metadata enrichment providers",
                count = counts.tagSources,
                onClick = { navController.navigate(AdminTagSources) },
            )
        }
    }
}

@Composable
private fun SectionCard(
    icon: ImageVector,
    title: String,
    subtitle: String,
    count: Int,
    onClick: () -> Unit,
) {
    ElevatedCard(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(onClick = onClick),
    ) {
        Row(
            modifier = Modifier.padding(16.dp),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(16.dp),
        ) {
            Icon(
                imageVector = icon,
                contentDescription = null,
                tint = MaterialTheme.colorScheme.primary,
                modifier = Modifier.size(32.dp),
            )
            Column(modifier = Modifier.weight(1f)) {
                Text(
                    text = title,
                    style = MaterialTheme.typography.titleMedium,
                    color = MaterialTheme.colorScheme.onSurface,
                )
                Text(
                    text = subtitle,
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant,
                )
            }
            Text(
                text = "$count",
                style = MaterialTheme.typography.titleLarge,
                color = MaterialTheme.colorScheme.primary,
            )
        }
    }
}
