package com.jttools.datacontrol.ui.settings

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.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerDialog
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.res.stringResource
import androidx.compose.ui.text.font.FontWeight
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.jttools.datacontrol.R
import com.jttools.datacontrol.ui.SystemActions
import com.jttools.datacontrol.ui.components.PasswordGate
import com.jttools.datacontrol.ui.theme.StateOk
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.Locale

@OptIn(androidx.compose.material3.ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(systemActions: SystemActions) {
    val viewModel: SettingsViewModel = hiltViewModel()
    val settings by viewModel.settings.collectAsStateWithLifecycle()

    PasswordGate(passwordSet = settings.hasPassword, verify = { viewModel.verifyPassword(it) }) {
        SettingsContent(systemActions, viewModel, settings)
    }
}

@OptIn(androidx.compose.material3.ExperimentalMaterial3Api::class)
@Composable
private fun SettingsContent(
    systemActions: SystemActions,
    viewModel: SettingsViewModel,
    settings: com.jttools.datacontrol.data.AppSettings
) {
    var planLimitText by remember(settings.planLimitMo) { mutableStateOf(settings.planLimitMo.toString()) }
    var planPriceText by remember(settings.planPriceEuro) { mutableStateOf(settings.planPriceEuro.toString()) }
    var overagePriceText by remember(settings.overagePricePerMoEuro) { mutableStateOf(settings.overagePricePerMoEuro.toString()) }
    var cutoffText by remember(settings.cutoffIntervalMinutes) { mutableStateOf(settings.cutoffIntervalMinutes.toString()) }
    var autoReset by remember(settings.autoResetEnabled) { mutableStateOf(settings.autoResetEnabled) }
    var showDatePicker by remember { mutableStateOf(false) }

    val consumedMo by viewModel.consumedMo.collectAsStateWithLifecycle()
    var showConsumedDialog by remember { mutableStateOf(false) }
    var consumedMoText by remember { mutableStateOf("") }

    var vpnGranted by remember { mutableStateOf(systemActions.isVpnPrepared()) }
    var notifGranted by remember { mutableStateOf(systemActions.hasNotificationPermission()) }
    var batteryIgnored by remember { mutableStateOf(systemActions.isIgnoringBatteryOptimizations()) }

    var newPassword by remember { mutableStateOf("") }
    var confirmPassword by remember { mutableStateOf("") }
    var passwordError by remember { mutableStateOf<String?>(null) }
    var passwordMessage by remember { mutableStateOf<String?>(null) }
    val passwordTooShort = stringResource(R.string.settings_password_too_short)
    val passwordMismatch = stringResource(R.string.settings_password_mismatch)
    val passwordSetMessage = stringResource(R.string.settings_password_set_confirmation)
    val passwordRemovedMessage = stringResource(R.string.settings_password_removed_confirmation)

    LaunchedEffect(Unit) {
        vpnGranted = systemActions.isVpnPrepared()
        notifGranted = systemActions.hasNotificationPermission()
        batteryIgnored = systemActions.isIgnoringBatteryOptimizations()
    }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState())
            .padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text(stringResource(R.string.settings_title), style = MaterialTheme.typography.headlineMedium)

        Card(shape = RoundedCornerShape(20.dp), elevation = CardDefaults.cardElevation(2.dp)) {
            Column(Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(14.dp)) {
                Text(stringResource(R.string.settings_section_plan), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)

                OutlinedTextField(
                    value = planLimitText,
                    onValueChange = { planLimitText = it.filter(Char::isDigit) },
                    label = { Text(stringResource(R.string.settings_plan_limit_mo)) },
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                    modifier = Modifier.fillMaxWidth()
                )
                OutlinedTextField(
                    value = planPriceText,
                    onValueChange = { planPriceText = it.filter { c -> c.isDigit() || c == '.' } },
                    label = { Text(stringResource(R.string.settings_plan_price)) },
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
                    modifier = Modifier.fillMaxWidth()
                )
                OutlinedTextField(
                    value = overagePriceText,
                    onValueChange = { overagePriceText = it.filter { c -> c.isDigit() || c == '.' } },
                    label = { Text(stringResource(R.string.settings_overage_price)) },
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
                    modifier = Modifier.fillMaxWidth()
                )

                Row(
                    Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Column {
                        Text(stringResource(R.string.settings_start_date), style = MaterialTheme.typography.bodyMedium)
                        Text(
                            settings.planStartDate.format(DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.FRENCH)),
                            style = MaterialTheme.typography.titleMedium,
                            fontWeight = FontWeight.SemiBold
                        )
                    }
                    OutlinedButton(onClick = { showDatePicker = true }) { Text(stringResource(R.string.settings_edit_date)) }
                }

                Row(
                    Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Column {
                        Text(stringResource(R.string.settings_current_consumption), style = MaterialTheme.typography.bodyMedium)
                        Text(
                            "$consumedMo Mo",
                            style = MaterialTheme.typography.titleMedium,
                            fontWeight = FontWeight.SemiBold
                        )
                    }
                    OutlinedButton(onClick = {
                        consumedMoText = consumedMo.toString()
                        showConsumedDialog = true
                    }) { Text(stringResource(R.string.settings_edit_date)) }
                }

                Row(
                    Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(stringResource(R.string.settings_auto_reset), style = MaterialTheme.typography.bodyMedium)
                    Switch(checked = autoReset, onCheckedChange = { autoReset = it })
                }
            }
        }

        Card(shape = RoundedCornerShape(20.dp), elevation = CardDefaults.cardElevation(2.dp)) {
            Column(Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
                Text(stringResource(R.string.settings_section_cutoff), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
                OutlinedTextField(
                    value = cutoffText,
                    onValueChange = { cutoffText = it.filter(Char::isDigit) },
                    label = { Text(stringResource(R.string.settings_cutoff_interval)) },
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                    modifier = Modifier.fillMaxWidth()
                )
                Text(
                    stringResource(R.string.settings_cutoff_help),
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        }

        Card(shape = RoundedCornerShape(20.dp), elevation = CardDefaults.cardElevation(2.dp)) {
            Column(Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(4.dp)) {
                Text(stringResource(R.string.settings_section_permissions), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
                HorizontalDivider()
                PermissionRow(
                    title = stringResource(R.string.settings_perm_vpn),
                    description = stringResource(R.string.settings_perm_vpn_desc),
                    granted = vpnGranted
                ) { systemActions.requestVpnPermission { vpnGranted = it } }

                PermissionRow(
                    title = stringResource(R.string.settings_perm_notifications),
                    description = stringResource(R.string.settings_perm_notifications_desc),
                    granted = notifGranted
                ) { systemActions.requestNotificationPermission { notifGranted = it } }

                PermissionRow(
                    title = stringResource(R.string.settings_perm_battery),
                    description = stringResource(R.string.settings_perm_battery_desc),
                    granted = batteryIgnored
                ) {
                    systemActions.requestIgnoreBatteryOptimizations()
                    batteryIgnored = systemActions.isIgnoringBatteryOptimizations()
                }
            }
        }

        Card(shape = RoundedCornerShape(20.dp), elevation = CardDefaults.cardElevation(2.dp)) {
            Column(Modifier.padding(20.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
                Text(stringResource(R.string.settings_section_security), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
                HorizontalDivider()
                Text(
                    if (settings.hasPassword) stringResource(R.string.settings_password_active)
                    else stringResource(R.string.settings_password_inactive),
                    style = MaterialTheme.typography.bodyMedium,
                    color = if (settings.hasPassword) StateOk else MaterialTheme.colorScheme.onSurfaceVariant
                )
                OutlinedTextField(
                    value = newPassword,
                    onValueChange = { newPassword = it; passwordError = null; passwordMessage = null },
                    label = { Text(stringResource(R.string.settings_password_new)) },
                    visualTransformation = PasswordVisualTransformation(),
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                    singleLine = true,
                    modifier = Modifier.fillMaxWidth()
                )
                OutlinedTextField(
                    value = confirmPassword,
                    onValueChange = { confirmPassword = it; passwordError = null; passwordMessage = null },
                    label = { Text(stringResource(R.string.settings_password_confirm)) },
                    visualTransformation = PasswordVisualTransformation(),
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                    singleLine = true,
                    modifier = Modifier.fillMaxWidth()
                )
                passwordError?.let {
                    Text(it, color = MaterialTheme.colorScheme.error, style = MaterialTheme.typography.bodySmall)
                }
                passwordMessage?.let {
                    Text(it, color = StateOk, style = MaterialTheme.typography.bodySmall)
                }
                Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
                    Button(onClick = {
                        when {
                            newPassword.length < 4 -> passwordError = passwordTooShort
                            newPassword != confirmPassword -> passwordError = passwordMismatch
                            else -> {
                                viewModel.setPassword(newPassword)
                                newPassword = ""
                                confirmPassword = ""
                                passwordError = null
                                passwordMessage = passwordSetMessage
                            }
                        }
                    }) { Text(stringResource(R.string.settings_password_set)) }

                    if (settings.hasPassword) {
                        OutlinedButton(onClick = {
                            viewModel.setPassword(null)
                            newPassword = ""
                            confirmPassword = ""
                            passwordError = null
                            passwordMessage = passwordRemovedMessage
                        }) { Text(stringResource(R.string.settings_password_remove)) }
                    }
                }
            }
        }

        Button(
            onClick = {
                viewModel.updatePlan(
                    planLimitMo = planLimitText.toLongOrNull() ?: settings.planLimitMo,
                    planPriceEuro = planPriceText.toDoubleOrNull() ?: settings.planPriceEuro,
                    overagePricePerMoEuro = overagePriceText.toDoubleOrNull() ?: settings.overagePricePerMoEuro,
                    cutoffIntervalMinutes = cutoffText.toIntOrNull()?.coerceAtLeast(1) ?: settings.cutoffIntervalMinutes,
                    autoResetEnabled = autoReset
                )
            },
            modifier = Modifier.fillMaxWidth()
        ) { Text(stringResource(R.string.settings_save)) }
    }

    if (showDatePicker) {
        val datePickerState = rememberDatePickerState(
            initialSelectedDateMillis = settings.planStartDate.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli()
        )
        DatePickerDialog(
            onDismissRequest = { showDatePicker = false },
            confirmButton = {
                Button(onClick = {
                    datePickerState.selectedDateMillis?.let { millis ->
                        val date = Instant.ofEpochMilli(millis).atZone(ZoneOffset.UTC).toLocalDate()
                        viewModel.setStartDate(date)
                    }
                    showDatePicker = false
                }) { Text(stringResource(R.string.common_confirm)) }
            },
            dismissButton = {
                OutlinedButton(onClick = { showDatePicker = false }) { Text(stringResource(R.string.common_cancel)) }
            }
        ) { DatePicker(state = datePickerState) }
    }

    if (showConsumedDialog) {
        AlertDialog(
            onDismissRequest = { showConsumedDialog = false },
            title = { Text(stringResource(R.string.settings_current_consumption)) },
            text = {
                OutlinedTextField(
                    value = consumedMoText,
                    onValueChange = { consumedMoText = it.filter(Char::isDigit) },
                    label = { Text(stringResource(R.string.settings_plan_limit_mo_unit)) },
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                    singleLine = true,
                    modifier = Modifier.fillMaxWidth()
                )
            },
            confirmButton = {
                Button(onClick = {
                    consumedMoText.toLongOrNull()?.let { viewModel.setConsumedMo(it.coerceAtLeast(0L)) }
                    showConsumedDialog = false
                }) { Text(stringResource(R.string.common_confirm)) }
            },
            dismissButton = {
                OutlinedButton(onClick = { showConsumedDialog = false }) { Text(stringResource(R.string.common_cancel)) }
            }
        )
    }
}

@Composable
private fun PermissionRow(title: String, description: String, granted: Boolean, onRequest: () -> Unit) {
    Row(
        Modifier.fillMaxWidth().padding(vertical = 10.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Column(Modifier.weight(1f)) {
            Text(title, style = MaterialTheme.typography.bodyLarge, fontWeight = FontWeight.Medium)
            Text(description, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
        }
        if (granted) {
            Text(
                stringResource(R.string.settings_perm_granted),
                color = com.jttools.datacontrol.ui.theme.StateOk,
                style = MaterialTheme.typography.labelLarge
            )
        } else {
            OutlinedButton(onClick = onRequest) { Text(stringResource(R.string.settings_perm_missing)) }
        }
    }
}
