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

import android.content.Intent
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.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
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.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontFamily
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 com.runicgateway.app.R
import com.runicgateway.app.ui.UiState
import com.runicgateway.app.ui.components.ShardCard

/**
 * Account → Recovery Codes (TRUSTED_DEVICES_MFA.md): shows the remaining count and a
 * password-stepped regenerate that reveals a fresh single-use batch **once**. The
 * codes are shown only in memory — copy or share them before leaving; they are never
 * stored on the device.
 */
@Composable
fun RecoveryCodesScreen(
    modifier: Modifier = Modifier,
    viewModel: RecoveryCodesViewModel = hiltViewModel(),
) {
    val state by viewModel.state.collectAsStateWithLifecycle()
    var currentPassword by rememberSaveable { mutableStateOf("") }

    Column(
        modifier = modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState())
            .padding(16.dp),
    ) {
        Text(stringResource(R.string.recovery_codes_title), style = MaterialTheme.typography.titleLarge)
        Text(
            stringResource(R.string.recovery_codes_subtitle),
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
            modifier = Modifier.padding(top = 4.dp),
        )

        val remainingText = when (val r = state.remaining) {
            is UiState.Success -> stringResource(R.string.recovery_codes_remaining, r.data)
            is UiState.Error -> stringResource(R.string.recovery_codes_remaining_unknown)
            UiState.Loading -> stringResource(R.string.recovery_codes_remaining_loading)
        }
        Text(remainingText, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(top = 16.dp))

        state.freshCodes?.let { codes ->
            RecoveryCodesShowOnceCard(codes, onDismiss = { viewModel.dismissFreshCodes(); currentPassword = "" })
        }

        OutlinedTextField(
            value = currentPassword,
            onValueChange = { currentPassword = it },
            singleLine = true,
            enabled = !state.busy,
            label = { Text(stringResource(R.string.account_password_current)) },
            supportingText = { Text(stringResource(R.string.recovery_codes_password_hint)) },
            visualTransformation = PasswordVisualTransformation(),
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
            modifier = Modifier.fillMaxWidth().padding(top = 20.dp),
        )

        state.error?.let { err ->
            Text(
                text = stringResource(err),
                color = MaterialTheme.colorScheme.error,
                style = MaterialTheme.typography.bodyMedium,
                modifier = Modifier.padding(top = 12.dp),
            )
        }

        Button(
            onClick = { viewModel.regenerate(currentPassword) },
            enabled = !state.busy,
            modifier = Modifier.fillMaxWidth().padding(top = 16.dp),
        ) { Text(stringResource(R.string.recovery_codes_regenerate)) }
    }
}

/**
 * A show-once display of a freshly generated recovery-code batch, with copy/share and
 * a dismiss. Shared by this screen and the "2FA just enabled" surface on AccountScreen.
 */
@Composable
fun RecoveryCodesShowOnceCard(codes: List<String>, onDismiss: () -> Unit) {
    val context = LocalContext.current
    val clipboard = LocalClipboardManager.current
    val joined = remember(codes) { codes.joinToString("\n") }

    ShardCard(Modifier.fillMaxWidth().padding(top = 16.dp)) {
        Column(Modifier.padding(16.dp)) {
            Text(stringResource(R.string.recovery_codes_new_title), style = MaterialTheme.typography.titleMedium)
            Text(
                stringResource(R.string.recovery_codes_new_hint),
                style = MaterialTheme.typography.bodySmall,
                color = MaterialTheme.colorScheme.onSurfaceVariant,
                modifier = Modifier.padding(top = 4.dp),
            )
            codes.forEach { code ->
                Text(
                    code,
                    style = MaterialTheme.typography.bodyLarge.copy(fontFamily = FontFamily.Monospace),
                    modifier = Modifier.padding(top = 8.dp),
                )
            }
            Row(Modifier.fillMaxWidth().padding(top = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                OutlinedButton(
                    onClick = { clipboard.setText(AnnotatedString(joined)) },
                ) { Text(stringResource(R.string.recovery_codes_copy)) }
                OutlinedButton(
                    onClick = {
                        val send = Intent(Intent.ACTION_SEND).apply {
                            type = "text/plain"
                            putExtra(Intent.EXTRA_TEXT, joined)
                        }
                        context.startActivity(Intent.createChooser(send, null))
                    },
                ) { Text(stringResource(R.string.recovery_codes_share)) }
                Button(onClick = onDismiss) { Text(stringResource(R.string.recovery_codes_done)) }
            }
        }
    }
}
