package com.garfiec.librechat.feature.settings.navigation

import androidx.compose.runtime.LaunchedEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavKey
import com.garfiec.librechat.feature.settings.screen.AccountSettingsScreen
import com.garfiec.librechat.feature.settings.screen.ApiKeysScreen
import com.garfiec.librechat.feature.settings.screen.ChatSettingsScreen
import com.garfiec.librechat.feature.settings.screen.DataSettingsScreen
import com.garfiec.librechat.feature.settings.screen.GeneralSettingsScreen
import com.garfiec.librechat.feature.settings.screen.PresetManagerScreen
import com.garfiec.librechat.feature.settings.screen.SharedLinksScreen
import com.garfiec.librechat.feature.settings.screen.TabbedSettingsScreen
import com.garfiec.librechat.feature.settings.viewmodel.SettingsViewModel
import kotlinx.serialization.Serializable
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
import org.koin.compose.viewmodel.koinViewModel

@Serializable sealed interface SettingsRoute : NavKey

@Serializable data object SettingsTabbed : SettingsRoute
@Serializable data object SettingsGeneral : SettingsRoute
@Serializable data object SettingsChat : SettingsRoute
@Serializable data object SettingsAccount : SettingsRoute
@Serializable data object SettingsData : SettingsRoute
@Serializable data object SharedLinks : SettingsRoute
@Serializable data object PresetManager : SettingsRoute
@Serializable data object ApiKeys : SettingsRoute

fun EntryProviderScope<NavKey>.settingsEntries(
    onNavigate: (NavKey) -> Unit,
    onBack: () -> Unit,
    onLogout: () -> Unit,
    onNavigateToArchived: () -> Unit = {},
) {
    entry<SettingsTabbed> {
        TabbedSettingsScreen(
            onNavigateBack = onBack,
            onLogout = onLogout,
            onNavigateToArchived = onNavigateToArchived,
            onNavigateToSharedLinks = { onNavigate(SharedLinks) },
            onNavigateToPresets = { onNavigate(PresetManager) },
            onNavigateToApiKeys = { onNavigate(ApiKeys) },
        )
    }
    entry<SettingsGeneral> {
        GeneralSettingsScreen(
            onNavigateBack = onBack,
        )
    }
    entry<SettingsChat> {
        ChatSettingsScreen(
            onNavigateBack = onBack,
            onNavigateToPresets = { onNavigate(PresetManager) },
        )
    }
    entry<SettingsAccount> {
        AccountSettingsScreen(
            onLogout = onLogout,
            onNavigateBack = onBack,
            onNavigateToApiKeys = { onNavigate(ApiKeys) },
        )
    }
    entry<SettingsData> {
        DataSettingsScreen(
            onNavigateBack = onBack,
            onNavigateToArchived = onNavigateToArchived,
            onNavigateToSharedLinks = { onNavigate(SharedLinks) },
        )
    }
    entry<SharedLinks> {
        val viewModel: SettingsViewModel = koinViewModel()
        val uiState = viewModel.uiState.collectAsStateWithLifecycle()

        LaunchedEffect(Unit) {
            viewModel.loadSharedLinks()
        }

        SharedLinksScreen(
            links = uiState.value.sharedLinks,
            isLoading = uiState.value.isSharedLinksLoading,
            hasNextPage = uiState.value.sharedLinksHasNextPage,
            serverUrl = uiState.value.serverUrl,
            onLoadMore = viewModel::loadMoreSharedLinks,
            onToggleVisibility = viewModel::toggleSharedLinkVisibility,
            onDelete = viewModel::deleteSharedLink,
            onNavigateBack = onBack,
        )
    }
    entry<PresetManager> {
        PresetManagerScreen(
            onNavigateBack = onBack,
        )
    }
    entry<ApiKeys> {
        ApiKeysScreen(
            onNavigateBack = onBack,
        )
    }
}

val settingsSerializersModule = SerializersModule {
    polymorphic(NavKey::class) {
        subclass(SettingsTabbed::class, SettingsTabbed.serializer())
        subclass(SettingsGeneral::class, SettingsGeneral.serializer())
        subclass(SettingsChat::class, SettingsChat.serializer())
        subclass(SettingsAccount::class, SettingsAccount.serializer())
        subclass(SettingsData::class, SettingsData.serializer())
        subclass(SharedLinks::class, SharedLinks.serializer())
        subclass(PresetManager::class, PresetManager.serializer())
        subclass(ApiKeys::class, ApiKeys.serializer())
        subclass(Memories::class, Memories.serializer())
        subclass(McpServers::class, McpServers.serializer())
    }
}
