package com.aiosman.riderpro.ui

import ChangePasswordScreen
import ImageViewer
import ModificationListScreen
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.aiosman.riderpro.LocalAnimatedContentScope
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.LocalSharedTransitionScope
import com.aiosman.riderpro.ui.account.AccountEditScreen2
import com.aiosman.riderpro.ui.account.ResetPasswordScreen
import com.aiosman.riderpro.ui.comment.CommentsScreen
import com.aiosman.riderpro.ui.favourite.FavouriteListPage
import com.aiosman.riderpro.ui.favourite.FavouriteNoticeScreen
import com.aiosman.riderpro.ui.follower.FollowerListScreen
import com.aiosman.riderpro.ui.follower.FollowerNoticeScreen
import com.aiosman.riderpro.ui.follower.FollowingListScreen
import com.aiosman.riderpro.ui.gallery.OfficialGalleryScreen
import com.aiosman.riderpro.ui.gallery.OfficialPhotographerScreen
import com.aiosman.riderpro.ui.gallery.ProfileTimelineScreen
import com.aiosman.riderpro.ui.index.IndexScreen
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
import com.aiosman.riderpro.ui.index.tabs.search.SearchScreen
import com.aiosman.riderpro.ui.like.LikeNoticeScreen
import com.aiosman.riderpro.ui.location.LocationDetailScreen
import com.aiosman.riderpro.ui.login.EmailSignupScreen
import com.aiosman.riderpro.ui.login.LoginPage
import com.aiosman.riderpro.ui.login.SignupScreen
import com.aiosman.riderpro.ui.login.UserAuthScreen
import com.aiosman.riderpro.ui.modification.EditModificationScreen
import com.aiosman.riderpro.ui.post.NewPostImageGridScreen
import com.aiosman.riderpro.ui.post.NewPostScreen
import com.aiosman.riderpro.ui.post.PostScreen
import com.aiosman.riderpro.ui.profile.AccountProfile

sealed class NavigationRoute(
    val route: String,
) {
    data object Index : NavigationRoute("Index")
    data object ProfileTimeline : NavigationRoute("ProfileTimeline")
    data object LocationDetail : NavigationRoute("LocationDetail/{x}/{y}")
    data object OfficialPhoto : NavigationRoute("OfficialPhoto")
    data object OfficialPhotographer : NavigationRoute("OfficialPhotographer")
    data object Post : NavigationRoute("Post/{id}")
    data object ModificationList : NavigationRoute("ModificationList")
    data object MyMessage : NavigationRoute("MyMessage")
    data object Comments : NavigationRoute("Comments")
    data object Likes : NavigationRoute("Likes")
    data object Followers : NavigationRoute("Followers")
    data object NewPost : NavigationRoute("NewPost")
    data object EditModification : NavigationRoute("EditModification")
    data object Login : NavigationRoute("Login")
    data object AccountProfile : NavigationRoute("AccountProfile/{id}")
    data object SignUp : NavigationRoute("SignUp")
    data object UserAuth : NavigationRoute("UserAuth")
    data object EmailSignUp : NavigationRoute("EmailSignUp")
    data object AccountEdit : NavigationRoute("AccountEditScreen")
    data object ImageViewer : NavigationRoute("ImageViewer")
    data object ChangePasswordScreen : NavigationRoute("ChangePasswordScreen")
    data object FavouritesScreen : NavigationRoute("FavouritesScreen")
    data object NewPostImageGrid : NavigationRoute("NewPostImageGrid")
    data object Search : NavigationRoute("Search")
    data object FollowerList : NavigationRoute("FollowerList/{id}")
    data object FollowingList : NavigationRoute("FollowingList/{id}")
    data object ResetPassword : NavigationRoute("ResetPassword")
    data object FavouriteList : NavigationRoute("FavouriteList")
}


@Composable
fun NavigationController(
    navController: NavHostController,
    startDestination: String = NavigationRoute.Login.route
) {
    val navigationBarHeight = with(LocalDensity.current) {
        WindowInsets.navigationBars.getBottom(this).toDp()
    }

    NavHost(
        navController = navController,
        startDestination = startDestination,
    ) {
        composable(route = NavigationRoute.Index.route) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                IndexScreen()
            }
        }
        composable(route = NavigationRoute.ProfileTimeline.route) {
            ProfileTimelineScreen()
        }
        composable(
            route = NavigationRoute.LocationDetail.route,
            arguments = listOf(
                navArgument("x") { type = NavType.FloatType },
                navArgument("y") { type = NavType.FloatType }
            )
        ) {
            Box(
                modifier = Modifier.padding(bottom = navigationBarHeight)
            ) {
                val x = it.arguments?.getFloat("x") ?: 0f
                val y = it.arguments?.getFloat("y") ?: 0f
                LocationDetailScreen(
                    x, y
                )
            }
        }
        composable(route = NavigationRoute.OfficialPhoto.route) {
            OfficialGalleryScreen()
        }
        composable(route = NavigationRoute.OfficialPhotographer.route) {
            OfficialPhotographerScreen()
        }
        composable(
            route = NavigationRoute.Post.route,
            arguments = listOf(navArgument("id") { type = NavType.StringType }),
        ) { backStackEntry ->
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                val id = backStackEntry.arguments?.getString("id")
                PostScreen(
                    id!!
                )
            }
        }
        composable(route = NavigationRoute.ModificationList.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            ModificationListScreen()
        }
        composable(route = NavigationRoute.MyMessage.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            NotificationsScreen()
        }
        composable(route = NavigationRoute.Comments.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            CommentsScreen()
        }
        composable(route = NavigationRoute.Likes.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            LikeNoticeScreen()
        }
        composable(route = NavigationRoute.Followers.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            FollowerNoticeScreen()
        }
        composable(
            route = NavigationRoute.NewPost.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            NewPostScreen()
        }
        composable(route = NavigationRoute.EditModification.route) {
            Box(
                modifier = Modifier.padding(top = 64.dp)
            ) {
                EditModificationScreen()
            }
        }
        composable(route = NavigationRoute.Login.route) {
            LoginPage()

        }
        composable(
            route = NavigationRoute.AccountProfile.route,
            arguments = listOf(navArgument("id") { type = NavType.StringType })
        ) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                AccountProfile(it.arguments?.getString("id")!!)
            }
        }
        composable(
            route = NavigationRoute.SignUp.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            SignupScreen()
        }
        composable(
            route = NavigationRoute.UserAuth.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            UserAuthScreen()
        }
        composable(
            route = NavigationRoute.EmailSignUp.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            EmailSignupScreen()
        }
        composable(
            route = NavigationRoute.AccountEdit.route,
            enterTransition = {
                fadeIn(animationSpec = tween(durationMillis = 0))
            },
            exitTransition = {
                fadeOut(animationSpec = tween(durationMillis = 0))
            }
        ) {
            AccountEditScreen2()
        }
        composable(route = NavigationRoute.ImageViewer.route) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                ImageViewer()
            }
        }
        composable(route = NavigationRoute.ChangePasswordScreen.route) {
            ChangePasswordScreen()
        }
        composable(route = NavigationRoute.FavouritesScreen.route) {
            FavouriteNoticeScreen()
        }
        composable(route = NavigationRoute.NewPostImageGrid.route) {
            NewPostImageGridScreen()
        }
        composable(route = NavigationRoute.Search.route) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                SearchScreen()
            }
        }
        composable(
            route = NavigationRoute.FollowerList.route,
            arguments = listOf(navArgument("id") { type = NavType.IntType })
        ) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                FollowerListScreen(it.arguments?.getInt("id")!!)
            }
        }
        composable(
            route = NavigationRoute.FollowingList.route,
            arguments = listOf(navArgument("id") { type = NavType.IntType })
        ) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                FollowingListScreen(it.arguments?.getInt("id")!!)
            }
        }
        composable(route = NavigationRoute.ResetPassword.route) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                ResetPasswordScreen()
            }
        }
        composable(route = NavigationRoute.FavouriteList.route) {
            CompositionLocalProvider(
                LocalAnimatedContentScope provides this,
            ) {
                FavouriteListPage()
            }
        }
    }


}

@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun Navigation(
    startDestination: String = NavigationRoute.Login.route,
    onLaunch: (navController: NavHostController) -> Unit
) {
    val navController = rememberNavController()
    LaunchedEffect(Unit) {
        onLaunch(navController)
    }
    SharedTransitionLayout {
        CompositionLocalProvider(
            LocalNavController provides navController,
            LocalSharedTransitionScope provides this@SharedTransitionLayout,
        ) {
            Box {
                NavigationController(
                    navController = navController,
                    startDestination = startDestination
                )
            }
        }
    }
}