@file:Suppress("HardCodedStringLiteral")

package eu.gaudian.translator.view.composable

import android.annotation.SuppressLint
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
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.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
import eu.gaudian.translator.R
import eu.gaudian.translator.ui.theme.ThemePreviews
import eu.gaudian.translator.view.LocalShowExperimentalFeatures

sealed class Screen(
    val route: String,
    val title: Int,
    val selectedIcon: ImageVector,
    val unselectedIcon: ImageVector
) {
    object Home : Screen("home", R.string.label_translation, AppIcons.TranslateFilled, AppIcons.TranslateOutlined)
    object Dictionary : Screen("dictionary", R.string.label_dictionary, AppIcons.DictionaryFilled, AppIcons.DictionaryOutlined)
    object Exercises : Screen("exercises", R.string.label_exercises, AppIcons.DictionaryFilled, AppIcons.DictionaryOutlined)
    object Vocabulary : Screen("vocabulary", R.string.label_vocabulary, AppIcons.VocabularyFilled, AppIcons.VocabularyOutlined)
    object Settings : Screen("settings", R.string.title_settings, AppIcons.SettingsFilled, AppIcons.SettingsOutlined)

    companion object {
        fun getAllScreens(showExperimental: Boolean = false): List<Screen> {
            val screens = mutableListOf(Home, Dictionary, Vocabulary, Settings)
            if (showExperimental) {
                screens.add(2, Exercises)
            }
            return screens
        }

        @Composable
        fun fromDestination(destination: NavDestination?): Screen {
            val showExperimental = LocalShowExperimentalFeatures.current
            return getAllScreens(showExperimental).find { screen ->
                destination?.hierarchy?.any { it.route == screen.route } == true
            } ?: Home
        }
    }
}

/**
 * A modernized Material 3 bottom navigation bar with spring animations and haptic feedback.
 */
@SuppressLint("UnusedBoxWithConstraintsScope")
@Composable
fun BottomNavigationBar(
    selectedItem: Screen,
    isVisible: Boolean,
    showLabels: Boolean,
    onItemSelected: (Screen) -> Unit,
    modifier: Modifier = Modifier,
) {
    val showExperimental = LocalShowExperimentalFeatures.current
    val screens = remember(showExperimental) { Screen.getAllScreens(showExperimental) }
    val haptic = LocalHapticFeedback.current

    AnimatedVisibility(
        visible = isVisible,
        enter = slideInVertically(
            animationSpec = androidx.compose.animation.core.tween(durationMillis = 220),
            initialOffsetY = { it }
        ),
        exit = slideOutVertically(
            animationSpec = androidx.compose.animation.core.tween(durationMillis = 220),
            targetOffsetY = { it }
        )
    ) {

        val baseHeight = if (showLabels) 80.dp else 56.dp
        val density = LocalDensity.current
        val navBarDp = with(density) { WindowInsets.navigationBars.getBottom(this).toDp() }
        val height = baseHeight + navBarDp

        NavigationBar(
            modifier = modifier.height(height),
            containerColor = MaterialTheme.colorScheme.surface, // Cleaner look than surfaceVariant
            tonalElevation = 8.dp, // Slight elevation for depth
        ) {
            screens.forEach { screen ->
                val isSelected = screen == selectedItem
                val title = stringResource(id = screen.title)

                // 1. Spring Animation for the Icon Scale
                val scale by animateFloatAsState(
                    targetValue = if (isSelected) 1.2f else 1.0f, // Subtle pop effect
                    animationSpec = spring(
                        dampingRatio = Spring.DampingRatioMediumBouncy,
                        stiffness = Spring.StiffnessLow
                    ),
                    label = "iconScale"
                )

                NavigationBarItem(
                    selected = isSelected,
                    onClick = {
                        if (!isSelected) {
                            haptic.performHapticFeedback(HapticFeedbackType.LongPress) // 2. Tactile feedback
                            onItemSelected(screen)
                        }
                    },
                    label = if (showLabels) {
                        {
                            Text(
                                text = title,
                                maxLines = 1,
                                fontSize = 10.sp,
                                fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal,
                                color = if(isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
                            )
                        }
                    } else null,
                    icon = {
                        // 3. Crossfade between Outlined and Filled icons
                        Crossfade(targetState = isSelected, label = "iconFade") { selected ->
                            Icon(
                                imageVector = if (selected) screen.selectedIcon else screen.unselectedIcon,
                                contentDescription = title,
                                modifier = Modifier.scale(scale) // Apply the spring scale
                            )
                        }
                    },
                    colors = NavigationBarItemDefaults.colors(
                        indicatorColor = MaterialTheme.colorScheme.primaryContainer,
                        selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer,
                        selectedTextColor = MaterialTheme.colorScheme.primary,
                        unselectedIconColor = MaterialTheme.colorScheme.onSurfaceVariant,
                        unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                )
            }
        }
    }
}

@ThemePreviews
@Composable
fun BottomNavigationBarPreview() {
    MaterialTheme {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(MaterialTheme.colorScheme.background),
            contentAlignment = Alignment.BottomCenter
        ) {
            BottomNavigationBar(
                selectedItem = Screen.Home,
                isVisible = true,
                showLabels = true,
                onItemSelected = {}
            )
        }
    }
}