package com.devlab.app

import android.Manifest
import android.app.AlertDialog
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
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.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.core.app.ActivityCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.devlab.app.data.api.SessionManager
import com.devlab.app.navigation.Screen
import com.devlab.app.ui.dashboard.DashboardScreen
import com.devlab.app.ui.login.LoginScreen
import com.devlab.app.ui.login.LoginViewModel
import com.devlab.app.ui.notifications.NotificationsScreen
import com.devlab.app.ui.profile.ProfileScreen
import com.devlab.app.ui.register.RegisterScreen
import com.devlab.app.ui.servers.ServerDetailScreen
import com.devlab.app.ui.servers.ServerListScreen
import com.devlab.app.ui.theme.ServerManagerTheme
import com.devlab.app.util.AppUpdater
import com.devlab.app.util.UpdateChecker
import com.devlab.app.worker.NotificationWorker
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        installSplashScreen()
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        requestNotificationPermission()
        checkForUpdates()
        NotificationWorker.checkNow(this)

        lifecycle.addObserver(LifecycleEventObserver { _, event ->
            when (event) {
                Lifecycle.Event.ON_RESUME -> {
                    ServerManagerApp.instance.notificationPoller?.start()
                    ServerManagerApp.instance.notificationPoller?.checkNow()
                }
                Lifecycle.Event.ON_PAUSE -> {
                    ServerManagerApp.instance.notificationPoller?.stop()
                }
                else -> {}
            }
        })

        setContent {
            ServerManagerTheme {
                AppRoot()
            }
        }
    }

    private fun requestNotificationPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS)
                != PackageManager.PERMISSION_GRANTED
            ) {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(Manifest.permission.POST_NOTIFICATIONS),
                    1001
                )
            }
        }
    }

    private fun checkForUpdates() {
        val versionName = try {
            packageManager.getPackageInfo(packageName, 0).versionName ?: "1.0.0"
        } catch (_: Exception) { "1.0.0" }
        lifecycleScope.launch {
            val updateInfo = UpdateChecker(versionName).check()
            if (updateInfo.hasUpdate) {
                if (updateInfo.forceUpdate) {
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("Update Required")
                        .setMessage("A new version (${updateInfo.version}) is required to continue.\n\n${updateInfo.releaseNotes}")
                        .setCancelable(false)
                        .setPositiveButton("Update Now") { _, _ ->
                            AppUpdater(this@MainActivity).downloadAndInstall(updateInfo.apkUrl)
                        }
                        .show()
                } else {
                    AlertDialog.Builder(this@MainActivity)
                        .setTitle("Update Available")
                        .setMessage("Version ${updateInfo.version} is now available.\n\n${updateInfo.releaseNotes}")
                        .setPositiveButton("Update Now") { _, _ ->
                            AppUpdater(this@MainActivity).downloadAndInstall(updateInfo.apkUrl)
                        }
                        .setNegativeButton("Later", null)
                        .show()
                }
            }
        }
    }
}

@Composable
fun AppRoot() {
    val context = androidx.compose.ui.platform.LocalContext.current
    val navController = rememberNavController()
    val loginViewModel: LoginViewModel = viewModel()
    var isLoggedIn by remember { mutableStateOf(false) }
    var unreadCount by remember { mutableIntStateOf(0) }

    LaunchedEffect(isLoggedIn) {
        if (isLoggedIn) {
            NotificationWorker.checkNow(context)
        }
    }

    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentDestination = navBackStackEntry?.destination

    val inLoggedInArea = currentDestination?.route in listOf(
        Screen.Dashboard.route,
        Screen.ServerList.route,
        Screen.Profile.route,
        Screen.Notifications.route
    )

    LaunchedEffect(Unit) {
        SessionManager.onLogoutRequest.collect { requested ->
            if (requested) {
                loginViewModel.logout()
                isLoggedIn = false
                navController.navigate(Screen.Login.route) {
                    popUpTo(0) { inclusive = true }
                }
                SessionManager.consumeLogoutRequest()
                SessionManager.restoreSession()
            }
        }
    }

    DisposableEffect(Unit) {
        ServerManagerApp.instance.notificationPoller?.onCountChanged = { count ->
            unreadCount = count
        }
        onDispose {
            ServerManagerApp.instance.notificationPoller?.onCountChanged = null
        }
    }

    Scaffold(
        bottomBar = {
            if (inLoggedInArea) {
                NavigationBar {
                    NavigationBarItem(
                        icon = { Icon(Icons.Default.Dashboard, contentDescription = null) },
                        label = { Text("Dashboard") },
                        selected = currentDestination?.hierarchy?.any { it.route == Screen.Dashboard.route } == true,
                        onClick = {
                            navController.navigate(Screen.Dashboard.route) {
                                popUpTo(navController.graph.findStartDestination().id) { saveState = true }
                                launchSingleTop = true
                                restoreState = true
                            }
                        }
                    )
                    NavigationBarItem(
                        icon = { Icon(Icons.Default.Dns, contentDescription = null) },
                        label = { Text("Servers") },
                        selected = currentDestination?.hierarchy?.any { it.route == Screen.ServerList.route } == true,
                        onClick = {
                            navController.navigate(Screen.ServerList.route) {
                                popUpTo(navController.graph.findStartDestination().id) { saveState = true }
                                launchSingleTop = true
                                restoreState = true
                            }
                        }
                    )
                    NavigationBarItem(
                        icon = {
                            BadgedBox(badge = {
                                if (unreadCount > 0) {
                                    Badge { Text("$unreadCount") }
                                }
                            }) {
                                Icon(Icons.Default.Notifications, contentDescription = null)
                            }
                        },
                        label = { Text("Alerts") },
                        selected = currentDestination?.hierarchy?.any { it.route == Screen.Notifications.route } == true,
                        onClick = {
                            navController.navigate(Screen.Notifications.route) {
                                popUpTo(navController.graph.findStartDestination().id) { saveState = true }
                                launchSingleTop = true
                                restoreState = true
                            }
                        }
                    )
                }
            }
        }
    ) { innerPadding ->
        NavHost(
            navController = navController,
            startDestination = if (isLoggedIn) Screen.Dashboard.route else Screen.Login.route,
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding),
            enterTransition = { slideInHorizontally(initialOffsetX = { it / 4 }) + fadeIn(animationSpec = tween(300)) },
            exitTransition = { fadeOut(animationSpec = tween(200)) },
            popEnterTransition = { fadeIn(animationSpec = tween(200)) },
            popExitTransition = { slideOutHorizontally(targetOffsetX = { it / 4 }) + fadeOut(animationSpec = tween(200)) }
        ) {
            composable(Screen.Login.route) {
                LoginScreen(
                    onConnected = {
                        isLoggedIn = true
                        navController.navigate(Screen.Dashboard.route) {
                            popUpTo(Screen.Login.route) { inclusive = true }
                        }
                    },
                    onRegisterClick = {
                        navController.navigate(Screen.Register.route)
                    },
                    viewModel = loginViewModel
                )
            }

            composable(Screen.Register.route) {
                RegisterScreen(
                    onRegistered = {
                        isLoggedIn = true
                        navController.navigate(Screen.Dashboard.route) {
                            popUpTo(Screen.Register.route) { inclusive = true }
                        }
                    },
                    onLoginClick = {
                        navController.popBackStack()
                    }
                )
            }

            composable(Screen.Dashboard.route) {
                DashboardScreen(
                    onLogout = {
                        loginViewModel.logout()
                        isLoggedIn = false
                        navController.navigate(Screen.Login.route) {
                            popUpTo(0) { inclusive = true }
                        }
                    },
                    onProfileClick = {
                        navController.navigate(Screen.Profile.route)
                    },
                    onNotificationsClick = {
                        navController.navigate(Screen.Notifications.route)
                    },
                    unreadCount = unreadCount
                )
            }

            composable(Screen.ServerList.route) {
                ServerListScreen(
                    onServerClick = { serverId ->
                        navController.navigate(Screen.ServerDetail.createRoute(serverId))
                    }
                )
            }

            composable(Screen.Notifications.route) {
                NotificationsScreen(
                    onBack = { navController.popBackStack() }
                )
            }

            composable(Screen.Profile.route) {
                ProfileScreen(
                    onBack = { navController.popBackStack() },
                    onLogout = {
                        loginViewModel.logout()
                        isLoggedIn = false
                        navController.navigate(Screen.Login.route) {
                            popUpTo(0) { inclusive = true }
                        }
                    }
                )
            }

            composable(
                route = Screen.ServerDetail.route,
                arguments = listOf(navArgument("serverId") { type = NavType.IntType })
            ) { backStackEntry ->
                val serverId = backStackEntry.arguments?.getInt("serverId") ?: 0
                ServerDetailScreen(
                    serverId = serverId,
                    onBack = { navController.popBackStack() }
                )
            }
        }
    }
}
