/*
 * 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.Intent
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.Storage
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.Storage
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import org.strongswan.android.R
import org.strongswan.android.data.VpnProfile
import org.strongswan.android.data.VpnProfileDataSource
import org.strongswan.android.logic.StrongSwanApplication
import org.strongswan.android.logic.TrustedCertificateManager
import org.strongswan.android.ui.LogActivity
import org.strongswan.android.ui.VpnProfileDetailActivity
import org.strongswan.android.ui.compose.theme.ShxTheme

fun ComponentActivity.installShxUi()
{
	enableEdgeToEdge()
	(application as StrongSwanApplication).executor.execute {
		TrustedCertificateManager.getInstance().load()
	}
	setContent {
		ShxTheme {
			Surface(Modifier.fillMaxSize()) {
				ShxApp()
			}
		}
	}
}

@Composable
fun ShxApp(viewModel: HomeViewModel = viewModel())
{
	val state by viewModel.ui.collectAsStateWithLifecycle()
	val context = LocalContext.current
	val addProfile = {
		context.startActivity(Intent(context, VpnProfileDetailActivity::class.java))
	}
	val editProfile: (VpnProfile) -> Unit = { profile ->
		val intent = Intent(context, VpnProfileDetailActivity::class.java)
		intent.putExtra(VpnProfileDataSource.KEY_UUID, profile.getUUID().toString())
		context.startActivity(intent)
	}

	Scaffold(
		bottomBar = {
			ShxBottomBar(selected = state.tab, onSelect = viewModel::setTab)
		},
		containerColor = MaterialTheme.colorScheme.background,
	) { padding ->
		Surface(
			modifier = Modifier
				.fillMaxSize()
				.padding(padding)
				.consumeWindowInsets(padding),
			color = MaterialTheme.colorScheme.background,
		) {
			AnimatedContent(
				targetState = state.tab,
				transitionSpec = {
					val forward = targetState.ordinal >= initialState.ordinal
					val direction = if (forward) 1 else -1
					(slideInHorizontally(tween(240)) { it / 6 * direction } + fadeIn(tween(240))) togetherWith
						(slideOutHorizontally(tween(180)) { -it / 6 * direction } + fadeOut(tween(160)))
				},
				label = "tabContent",
			) { tab ->
				when (tab)
				{
				ShxTab.HOME -> HomeScreen(
					state = state,
					trafficFlow = viewModel.traffic,
					viewModel = viewModel,
						onAddProfile = addProfile,
						onEditProfile = editProfile,
						onShowLog = {
							context.startActivity(Intent(context, LogActivity::class.java))
						},
					)
					ShxTab.PROFILES -> ProfilesScreen(
						state = state,
						onConnect = { profile -> viewModel.connect(context, profile) },
						onDisconnect = { viewModel.disconnect() },
						onEdit = editProfile,
						onDelete = viewModel::delete,
						onAdd = addProfile,
					)
					ShxTab.SETTINGS -> SettingsScreen(profiles = state.profiles)
				}
			}
		}
	}
}

@Composable
private fun ShxBottomBar(selected: ShxTab, onSelect: (ShxTab) -> Unit)
{
	val bg = MaterialTheme.colorScheme.surfaceContainer
	val indicator = MaterialTheme.colorScheme.primary.copy(alpha = 0.32f).compositeOver(bg)
	NavigationBar(containerColor = bg, tonalElevation = 0.dp) {
		ShxTab.entries.forEach { tab ->
			NavigationBarItem(
				selected = tab == selected,
				onClick = { onSelect(tab) },
				icon = {
					Icon(
						imageVector = tab.icon(selected = tab == selected),
						contentDescription = null,
					)
				},
				label = { Text(stringResource(tab.label())) },
				colors = NavigationBarItemDefaults.colors(
					selectedIconColor = MaterialTheme.colorScheme.primary,
					unselectedIconColor = MaterialTheme.colorScheme.onSurfaceVariant,
					selectedTextColor = MaterialTheme.colorScheme.primary,
					unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant,
					indicatorColor = indicator,
				),
			)
		}
	}
}

private fun ShxTab.icon(selected: Boolean): ImageVector = when (this)
{
	ShxTab.HOME -> if (selected) Icons.Filled.Home else Icons.Outlined.Home
	ShxTab.PROFILES -> if (selected) Icons.Filled.Storage else Icons.Outlined.Storage
	ShxTab.SETTINGS -> if (selected) Icons.Filled.Settings else Icons.Outlined.Settings
}

private fun ShxTab.label(): Int = when (this)
{
	ShxTab.HOME -> R.string.nav_connect
	ShxTab.PROFILES -> R.string.nav_profiles
	ShxTab.SETTINGS -> R.string.nav_settings
}
