package com.fabledsword.minstrel.admin.ui

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.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
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.AdminTagSourceRef
import com.fabledsword.minstrel.models.TagSourceTestResult
import com.fabledsword.minstrel.nav.AdminTagSources
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 AdminTagSourcesScreen(
    navController: NavHostController,
    viewModel: AdminTagSourcesViewModel = hiltViewModel(),
) {
    val state by viewModel.uiState.collectAsStateWithLifecycle()
    Scaffold(
        contentWindowInsets = ShellContentWindowInsets,
        modifier = Modifier.fillMaxSize(),
        topBar = {
            MinstrelTopAppBar(
                title = "Admin · Tag sources",
                navController = navController,
                currentRouteName = AdminTagSources::class.qualifiedName,
                onBack = { navController.popBackStack() },
            )
        },
    ) { inner ->
        PullToRefreshScaffold(
            onRefresh = { viewModel.refresh().join() },
            modifier = Modifier.fillMaxSize().padding(inner),
        ) {
            when (val s = state) {
                AdminTagSourcesUiState.Loading -> LoadingCentered()
                AdminTagSourcesUiState.Empty -> EmptyState(
                    title = "No tag sources",
                    body = "Tag-enrichment providers register on the server; none are available.",
                )
                is AdminTagSourcesUiState.Error -> ErrorRetry(
                    title = "Couldn't load tag sources",
                    message = s.message,
                    onRetry = { viewModel.refresh() },
                )
                is AdminTagSourcesUiState.Success -> TagSourceList(
                    providers = s.providers,
                    testResults = s.testResults,
                    onToggle = viewModel::setEnabled,
                    onSaveKey = viewModel::saveApiKey,
                    onTest = viewModel::test,
                )
            }
        }
    }
}

@Composable
private fun TagSourceList(
    providers: List<AdminTagSourceRef>,
    testResults: Map<String, TagSourceTestResult>,
    onToggle: (String, Boolean) -> Unit,
    onSaveKey: (String, String) -> Unit,
    onTest: (String) -> Unit,
) {
    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        items(items = providers, key = { it.id }) { provider ->
            TagSourceCard(
                provider = provider,
                testResult = testResults[provider.id],
                onToggle = onToggle,
                onSaveKey = onSaveKey,
                onTest = onTest,
            )
        }
    }
}

@Composable
private fun TagSourceCard(
    provider: AdminTagSourceRef,
    testResult: TagSourceTestResult?,
    onToggle: (String, Boolean) -> Unit,
    onSaveKey: (String, String) -> Unit,
    onTest: (String) -> Unit,
) {
    ElevatedCard(modifier = Modifier.fillMaxWidth()) {
        Column(
            modifier = Modifier.fillMaxWidth().padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(10.dp),
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.SpaceBetween,
            ) {
                Column(modifier = Modifier.weight(1f)) {
                    Text(provider.displayName, style = MaterialTheme.typography.titleMedium)
                    Text(
                        text = provider.supports.joinToString(", ") { it.replace('_', ' ') },
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant,
                    )
                }
                Switch(
                    checked = provider.enabled,
                    onCheckedChange = { onToggle(provider.id, it) },
                )
            }
            if (provider.requiresApiKey) {
                ApiKeyRow(provider = provider, onSaveKey = onSaveKey)
            }
            if (provider.testable) {
                TestRow(provider = provider, testResult = testResult, onTest = onTest)
            }
        }
    }
}

@Composable
private fun ApiKeyRow(provider: AdminTagSourceRef, onSaveKey: (String, String) -> Unit) {
    var key by remember(provider.id) { mutableStateOf("") }
    OutlinedTextField(
        value = key,
        onValueChange = { key = it },
        modifier = Modifier.fillMaxWidth(),
        label = { Text("API key") },
        placeholder = {
            Text(
                if (provider.apiKeySet) {
                    "••• saved — leave blank to keep"
                } else {
                    "Paste your API key to enable this source"
                },
            )
        },
        singleLine = true,
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
    )
    Row(
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Button(
            onClick = {
                onSaveKey(provider.id, key)
                key = ""
            },
            enabled = key.isNotBlank(),
        ) { Text("Save key") }
        if (provider.apiKeySet) {
            Text("✓ Set", style = MaterialTheme.typography.bodySmall)
        }
    }
}

@Composable
private fun TestRow(
    provider: AdminTagSourceRef,
    testResult: TagSourceTestResult?,
    onTest: (String) -> Unit,
) {
    Row(
        horizontalArrangement = Arrangement.spacedBy(8.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        OutlinedButton(onClick = { onTest(provider.id) }) { Text("Test connection") }
        testResult?.let { result ->
            if (result.ok) {
                Text(
                    text = "OK (${result.durationMs}ms)",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.primary,
                )
            } else {
                Text(
                    text = "Failed — ${result.error}",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.error,
                )
            }
        }
    }
}
