/*
 * Copyright (C) 2026 SHX VPN
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 */

package org.strongswan.android.ui.compose

import android.content.Context
import android.content.Intent
import android.os.Build
import android.provider.Settings
import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.KeyboardArrowRight
import androidx.compose.material.icons.rounded.BatteryChargingFull
import androidx.compose.material.icons.rounded.Cached
import androidx.compose.material.icons.rounded.Description
import androidx.compose.material.icons.rounded.FileDownload
import androidx.compose.material.icons.rounded.History
import androidx.compose.material.icons.rounded.Key
import androidx.compose.material.icons.rounded.Security
import androidx.compose.material.icons.rounded.VerifiedUser
import androidx.compose.material.icons.rounded.Wifi
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
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.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.preference.PreferenceManager
import org.strongswan.android.R
import org.strongswan.android.data.VpnProfile
import org.strongswan.android.logic.StrongSwanApplication
import org.strongswan.android.ui.LogActivity
import org.strongswan.android.ui.TrustedCertificatesActivity
import org.strongswan.android.ui.TrustedNetworksActivity
import org.strongswan.android.ui.VpnProfileImportActivity
import org.strongswan.android.ui.compose.theme.ScreenPadding
import org.strongswan.android.utils.Constants

@OptIn(androidx.compose.material3.ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(profiles: List<VpnProfile>, showTitle: Boolean = true)
{
	val context = LocalContext.current
	val prefs = remember { PreferenceManager.getDefaultSharedPreferences(context) }
	val managed = remember { StrongSwanApplication.getInstance().managedConfigurationService.managedConfiguration }
	var defaultUuid by remember {
		mutableStateOf(prefs.getString(Constants.PREF_DEFAULT_VPN_PROFILE, Constants.PREF_DEFAULT_VPN_PROFILE_MRU)
			?: Constants.PREF_DEFAULT_VPN_PROFILE_MRU)
	}
	var ignorePower by remember { mutableStateOf(prefs.getBoolean(Constants.PREF_IGNORE_POWER_WHITELIST, false)) }
	var showDefaultPicker by remember { mutableStateOf(false) }
	var showCrl by remember { mutableStateOf(false) }
	val versionName = remember {
		try
		{
			context.packageManager.getPackageInfo(context.packageName, 0).versionName ?: ""
		}
		catch (_: Exception)
		{
			""
		}
	}
	val defaultLabel = if (defaultUuid == Constants.PREF_DEFAULT_VPN_PROFILE_MRU)
		stringResource(R.string.pref_default_vpn_profile_mru)
	else profiles.firstOrNull { it.getUUID().toString() == defaultUuid }?.name
		?: stringResource(R.string.profile_not_found)

	Column(
		Modifier
			.fillMaxSize()
			.verticalScroll(rememberScrollState())
			.padding(bottom = 24.dp),
	)
	{
		if (showTitle)
		{
			TopAppBar(
				title = { Text(stringResource(R.string.pref_title), fontWeight = FontWeight.SemiBold) },
				colors = androidx.compose.material3.TopAppBarDefaults.topAppBarColors(
					containerColor = MaterialTheme.colorScheme.background,
				),
			)
		}

		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && managed.isAllowSettingsAccess)
		{
			SettingsSection(title = stringResource(R.string.settings_section_general))
			{
				SettingsRow(
					icon = Icons.Rounded.History,
					title = stringResource(R.string.pref_default_vpn_profile),
					subtitle = defaultLabel,
					onClick = { showDefaultPicker = true },
				)
				SettingsDivider()
				SettingsToggleRow(
					icon = Icons.Rounded.BatteryChargingFull,
					title = stringResource(R.string.pref_power_whitelist_title),
					subtitle = stringResource(R.string.pref_power_whitelist_summary),
					checked = ignorePower,
					onCheckedChange = {
						ignorePower = it
						prefs.edit().putBoolean(Constants.PREF_IGNORE_POWER_WHITELIST, it).apply()
					},
				)
			}
		}

		SettingsSection(title = stringResource(R.string.settings_section_automation))
		{
			SettingsRow(
				icon = Icons.Rounded.Wifi,
				title = stringResource(R.string.auto_connect_title),
				subtitle = stringResource(R.string.auto_connect_summary),
				onClick = {
					context.startActivity(Intent(context, TrustedNetworksActivity::class.java))
				},
			)
		}

		SettingsSection(title = stringResource(R.string.settings_section_security))
		{
			val lockdownActive = remember { context.isVpnLockdownEnabled() }
			SettingsRow(
				icon = Icons.Rounded.Security,
				title = stringResource(R.string.kill_switch_title),
				subtitle = stringResource(
					if (lockdownActive) R.string.kill_switch_summary_on
					else R.string.kill_switch_summary_off
				),
				onClick = {
					context.startActivity(Intent(Settings.ACTION_VPN_SETTINGS))
				},
			)
		}

		SettingsSection(title = stringResource(R.string.settings_section_certs))
		{
			SettingsRow(
				icon = Icons.Rounded.VerifiedUser,
				title = stringResource(R.string.trusted_certs_title),
				onClick = {
					context.startActivity(Intent(context, TrustedCertificatesActivity::class.java))
				},
			)
			SettingsDivider()
			SettingsRow(
				icon = Icons.Rounded.Cached,
				title = stringResource(R.string.crl_cache),
				onClick = { showCrl = true },
			)
		}

		if (managed.isAllowProfileImport)
		{
			SettingsSection(title = stringResource(R.string.settings_section_profiles))
			{
				SettingsRow(
					icon = Icons.Rounded.FileDownload,
					title = stringResource(R.string.profile_import),
					onClick = {
						context.startActivity(Intent(context, VpnProfileImportActivity::class.java))
					},
				)
			}
		}

		SettingsSection(title = stringResource(R.string.settings_section_support))
		{
			SettingsRow(
				icon = Icons.Rounded.Description,
				title = stringResource(R.string.show_log),
				onClick = {
					context.startActivity(Intent(context, LogActivity::class.java))
				},
			)
		}

		Text(
			text = stringResource(R.string.app_version_fmt, versionName),
			style = MaterialTheme.typography.bodySmall,
			color = MaterialTheme.colorScheme.onSurfaceVariant,
			modifier = Modifier
				.fillMaxWidth()
				.padding(top = 16.dp),
			textAlign = androidx.compose.ui.text.style.TextAlign.Center,
		)
	}

	if (showDefaultPicker)
	{
		val options = listOf(Constants.PREF_DEFAULT_VPN_PROFILE_MRU to context.getString(R.string.pref_default_vpn_profile_mru)) +
			profiles.map { it.getUUID().toString() to (it.name ?: "") }
		AlertDialog(
			onDismissRequest = { showDefaultPicker = false },
			title = { Text(stringResource(R.string.pref_default_vpn_profile)) },
			text = {
				Column {
					options.forEach { (value, label) ->
						Row(
							verticalAlignment = Alignment.CenterVertically,
							modifier = Modifier
								.fillMaxWidth()
								.clickable {
									defaultUuid = value
									prefs.edit().putString(Constants.PREF_DEFAULT_VPN_PROFILE, value).apply()
									showDefaultPicker = false
								}
								.padding(vertical = 10.dp),
						)
						{
							RadioButton(selected = defaultUuid == value, onClick = null)
							Text(label, modifier = Modifier.padding(start = 12.dp))
						}
					}
				}
			},
			confirmButton = {
				TextButton(onClick = { showDefaultPicker = false }) {
					Text(stringResource(android.R.string.cancel))
				}
			},
		)
	}

	if (showCrl)
	{
		val files = remember(showCrl) { context.fileList().filter { it.startsWith("crl-") } }
		AlertDialog(
			onDismissRequest = { showCrl = false },
			title = { Text(stringResource(R.string.clear_crl_cache_title)) },
			text = {
				Text(
					if (files.isEmpty()) stringResource(R.string.clear_crl_cache_msg_none)
					else stringResource(R.string.clear_crl_cache_title)
				)
			},
			confirmButton = {
				TextButton(onClick = {
					if (files.isEmpty())
					{
						Toast.makeText(context, R.string.clear_crl_cache_msg_none, Toast.LENGTH_SHORT).show()
					}
					else
					{
						files.forEach { context.deleteFile(it) }
					}
					showCrl = false
				}) { Text(stringResource(R.string.clear)) }
			},
			dismissButton = {
				TextButton(onClick = { showCrl = false }) {
					Text(stringResource(android.R.string.cancel))
				}
			},
		)
	}
}

@Composable
private fun SettingsSection(title: String, content: @Composable () -> Unit)
{
	Text(
		text = title.uppercase(),
		style = MaterialTheme.typography.labelMedium,
		color = MaterialTheme.colorScheme.onSurfaceVariant,
		modifier = Modifier
			.fillMaxWidth()
			.padding(start = ScreenPadding + 16.dp, top = 20.dp, bottom = 8.dp),
	)
	Surface(
		shape = MaterialTheme.shapes.large,
		color = MaterialTheme.colorScheme.surfaceContainerLow,
		modifier = Modifier
			.fillMaxWidth()
			.padding(horizontal = ScreenPadding),
	)
	{
		Column { content() }
	}
}

@Composable
private fun SettingsDivider()
{
	HorizontalDivider(
		color = MaterialTheme.colorScheme.outlineVariant.copy(alpha = 0.6f),
		modifier = Modifier.padding(start = 68.dp),
	)
}

@Composable
private fun SettingsIconWrapper(icon: ImageVector, tint: androidx.compose.ui.graphics.Color)
{
	Box(
		modifier = Modifier
			.size(36.dp)
			.background(MaterialTheme.colorScheme.primaryContainer, CircleShape),
		contentAlignment = Alignment.Center,
	) {
		Icon(
			imageVector = icon,
			contentDescription = null,
			tint = tint,
			modifier = Modifier.size(20.dp),
		)
	}
}

@Composable
private fun SettingsRow(
	icon: ImageVector,
	title: String,
	subtitle: String? = null,
	onClick: () -> Unit,
)
{
	Row(
		verticalAlignment = Alignment.CenterVertically,
		modifier = Modifier
			.fillMaxWidth()
			.clickable(onClick = onClick)
			.padding(horizontal = 16.dp, vertical = 14.dp),
	)
	{
		SettingsIconWrapper(icon = icon, tint = MaterialTheme.colorScheme.primary)
		Column(
			modifier = Modifier
				.weight(1f)
				.padding(horizontal = 16.dp),
		)
		{
			Text(title, style = MaterialTheme.typography.bodyLarge)
			if (subtitle != null)
			{
				Text(
					subtitle,
					style = MaterialTheme.typography.bodySmall,
					color = MaterialTheme.colorScheme.onSurfaceVariant,
				)
			}
		}
		Icon(
			Icons.AutoMirrored.Rounded.KeyboardArrowRight,
			contentDescription = null,
			tint = MaterialTheme.colorScheme.onSurfaceVariant,
		)
	}
}

@Composable
private fun SettingsToggleRow(
	icon: ImageVector,
	title: String,
	subtitle: String?,
	checked: Boolean,
	onCheckedChange: (Boolean) -> Unit,
)
{
	Row(
		verticalAlignment = Alignment.CenterVertically,
		modifier = Modifier
			.fillMaxWidth()
			.padding(horizontal = 16.dp, vertical = 14.dp),
	)
	{
		SettingsIconWrapper(icon = icon, tint = MaterialTheme.colorScheme.primary)
		Column(
			modifier = Modifier
				.weight(1f)
				.padding(horizontal = 16.dp),
		)
		{
			Text(title, style = MaterialTheme.typography.bodyLarge)
			if (subtitle != null)
			{
				Text(
					subtitle,
					style = MaterialTheme.typography.bodySmall,
					color = MaterialTheme.colorScheme.onSurfaceVariant,
				)
			}
		}
		Switch(checked = checked, onCheckedChange = onCheckedChange)
	}
}

/**
 * Checks whether the system-level lockdown ("Block connections without VPN") is
 * active for our package. Returns false if not determinable.
 */
private fun Context.isVpnLockdownEnabled(): Boolean
{
	return try
	{
		Settings.Global.getInt(
			contentResolver,
			"vpn_lockdown_$packageName",
			0
		) != 0
	}
	catch (_: Exception)
	{
		false
	}
}
