package com.mybus17000.data

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.location.Geocoder
import android.util.Log
import androidx.activity.result.ActivityResultLauncher
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.updateTransition
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.DirectionsBus
import androidx.compose.material.icons.filled.Place
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.google.android.gms.maps.model.LatLng
import kotlinx.coroutines.delay
import java.util.Locale
import kotlin.math.atan2
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
import kotlin.math.sqrt

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AddressOrStopSearchBar(
    addressQuery: String,
    onQueryChange: (String) -> Unit,
    stops: List<StopFields>,
    //addressSuggestions: List<String>,
    onSuggestionClick: (String) -> Unit,
    onAddFavorite: (String) -> Unit,
    onSearchClick: () -> Unit,
    modifier: Modifier
    //isAddressDetected: Boolean
    //speechLauncher: ActivityResultLauncher<Intent>,
) {
    var expanded by remember { mutableStateOf(false) }
    var isFocused by remember { mutableStateOf(false) }

    val focusRequester = remember { FocusRequester() }
    val transition = updateTransition(targetState = isFocused, label = "focusTransition")

    // Animation visuelle
    val elevation by transition.animateDp(label = "elevationAnim") { if (it) 10.dp else 4.dp }
    val yOffset by transition.animateDp(label = "offsetAnim") { if (it) (-4).dp else 0.dp }
    val scale by transition.animateFloat(label = "scaleAnim") { if (it) 1.02f else 1f }

    // États internes
    val addressSuggestions = remember { mutableStateListOf<String>() }
    val allSuggestions = remember { mutableStateListOf<String>() }
    var isAddressDetected by remember { mutableStateOf(false) }

    // Charger les suggestions (adresse + arrêts)
    LaunchedEffect(addressQuery) {
        if (addressQuery.isNotBlank()) {
            delay(300)
            val results = fetchAddresses(addressQuery)
            addressSuggestions.clear()
            addressSuggestions.addAll(results)
            isAddressDetected = results.isNotEmpty()

            allSuggestions.clear()
            allSuggestions.addAll(
                (results + stops.map { it.stop_name })
                    .filter { it.contains(addressQuery, ignoreCase = true) }
                    .distinct()
                    .take(8)
            )
            expanded = allSuggestions.isNotEmpty()
        } else {
            addressSuggestions.clear()
            allSuggestions.clear()
            isAddressDetected = false
            expanded = false
        }
    }

    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 12.dp)
            .offset(y = yOffset)
            .scale(scale)
    ) {
        // Barre principale (style Waze)
        Card(
            modifier = Modifier.fillMaxWidth(),
            shape = RoundedCornerShape(50),
            elevation = CardDefaults.cardElevation(elevation),
            colors = CardDefaults.cardColors(containerColor = Color.White),
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically,
                modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp)
            ) {
                // 🔍 Bouton de recherche
                IconButton(onClick = onSearchClick) {
                    Icon(
                        imageVector = Icons.Default.Search,
                        contentDescription = "Rechercher",
                        tint = Color(0xFF4285F4)
                    )
                }

                // ✏️ Champ de saisie
                TextField(
                    value = addressQuery,
                    onValueChange = {
                        onQueryChange(it)
                        expanded = it.isNotEmpty()
                    },
                    placeholder = { Text("Où allons-nous ?", color = Color.Gray) },
                    modifier = Modifier
                        .weight(1f)
                        .focusRequester(focusRequester)
                        .onFocusChanged { focusState ->
                            isFocused = focusState.isFocused
                        },
                    colors = TextFieldDefaults.colors(
                        focusedContainerColor = Color.Transparent,
                        unfocusedContainerColor = Color.Transparent,
                        focusedIndicatorColor = Color.Transparent,
                        unfocusedIndicatorColor = Color.Transparent,
                        cursorColor = Color(0xFF4285F4)
                    ),
                    textStyle = LocalTextStyle.current.copy(fontSize = 16.sp),
                    singleLine = true
                )

                // ✅ Adresse détectée
                if (isAddressDetected) {
                    Icon(
                        imageVector = Icons.Default.Check,
                        contentDescription = "Adresse détectée",
                        tint = Color(0xFF4CAF50),
                        modifier = Modifier
                            .size(26.dp)
                            .padding(start = 4.dp)
                    )
                }

                // ⭐ Favori et ❌ effacer
                if (addressQuery.isNotEmpty()) {
                    IconButton(onClick = { onAddFavorite(addressQuery) }) {
                        Icon(
                            imageVector = Icons.Default.Star,
                            contentDescription = "Favori",
                            tint = Color(0xFF4285F4)
                        )
                    }
                    IconButton(onClick = {
                        onQueryChange("")
                    }) {
                        Icon(
                            imageVector = Icons.Default.Close,
                            contentDescription = "Effacer",
                            tint = Color(0xFF4285F4)
                        )
                    }
                }
            }
        }

        // 🔽 Liste des suggestions
        AnimatedVisibility(
            visible = expanded && allSuggestions.isNotEmpty(),
            enter = fadeIn() + expandVertically(),
            exit = fadeOut() + shrinkVertically()
        ) {
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 8.dp)
                    .shadow(8.dp, RoundedCornerShape(16.dp)),
                shape = RoundedCornerShape(16.dp),
                colors = CardDefaults.cardColors(containerColor = Color.White)
            ) {
                Column {
                    allSuggestions.forEach { suggestion ->
                        DropdownMenuItem(
                            leadingIcon = {
                                Icon(
                                    imageVector = if (stops.any { it.stop_name == suggestion })
                                        Icons.Default.DirectionsBus else Icons.Default.Place,
                                    contentDescription = null,
                                    tint = if (stops.any { it.stop_name == suggestion })
                                        MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary
                                )
                            },
                            text = { Text(suggestion) },
                            onClick = {
                                onQueryChange(suggestion)
                                onSuggestionClick(suggestion)
                                expanded = false
                            }
                        )
                    }
                }
            }
        }
    }
}

@Composable
fun DropdownSuggestions(
    suggestions: List<String>,
    onSelect: (String) -> Unit
) {
    if (suggestions.isNotEmpty()) {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(vertical = 4.dp),
            elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
            shape = RoundedCornerShape(8.dp)
        ) {
            Column {
                suggestions.take(5).forEach { suggestion ->
                    Text(
                        text = suggestion,
                        modifier = Modifier
                            .clickable { onSelect(suggestion) }
                            .padding(horizontal = 12.dp, vertical = 8.dp)
                            .fillMaxWidth(),
                        style = MaterialTheme.typography.bodyMedium
                    )
                }
            }
        }
    }
}
suspend fun geocodeAddressSuggestions(context: Context, query: String): List<String> {
    return try {
        val geocoder = Geocoder(context, Locale.getDefault())
        val results = geocoder.getFromLocationName(query, 5)
        results?.mapNotNull { it.getAddressLine(0) } ?: emptyList()
    } catch (e: Exception) {
        Log.e("RouteSearchPanel", "Erreur suggestions: ${e.message}")
        emptyList()
    }
}


fun findNearestStopWithDistance(
    currentLocation: LatLng,
    stops: List<StopFields>
): Pair<StopFields, Double>? {
    if (stops.isEmpty()) return null

    fun haversineDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
        val R = 6371e3
        val phi1 = Math.toRadians(lat1)
        val phi2 = Math.toRadians(lat2)
        val deltaPhi = Math.toRadians(lat2 - lat1)
        val deltaLambda = Math.toRadians(lon2 - lon1)
        val a = sin(deltaPhi / 2).pow(2.0) + cos(phi1) * cos(phi2) * sin(deltaLambda / 2).pow(2.0)
        val c = 2 * atan2(sqrt(a), sqrt(1 - a))
        return R * c
    }

    return stops.mapNotNull { stop ->
        val lat = stop.stop_lat.toDoubleOrNull()
        val lon = stop.stop_lon.toDoubleOrNull()
        if (lat != null && lon != null) stop to haversineDistance(currentLocation.latitude, currentLocation.longitude, lat, lon)
        else null
    }.minByOrNull { it.second }
}


fun findNearestStops(point: LatLng, stops: List<StopFields>, limit: Int = 2): List<Pair<StopFields, Double>> {
    return stops
        // 🔹 Ne garde que les vrais arrêts physiques
        .filter { it.location_type == "1" }
        .map { stop ->
        val distance = distanceBetween(
            point.latitude, point.longitude,
            stop.stop_lat.toDouble(), stop.stop_lon.toDouble()
        )
        stop to distance
        }
        // 🔹 Regroupe les arrêts par stop_id et garde le plus proche pour chacun
        .groupBy { it.first.stop_id }
        .mapValues { (_, group) -> group.minByOrNull { it.second }!! }
        .values
        // 🔹 Trie par distance croissante
        .sortedBy { it.second }
        // 🔹 Garde les N premiers
        .take(limit)
}

fun distanceBetween(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
    val result = FloatArray(1)
    android.location.Location.distanceBetween(lat1, lon1, lat2, lon2, result)
    return result[0].toDouble()
}
//@OptIn(ExperimentalMaterial3Api::class)
//@Composable
//fun AddressOrStopSearchBar(
//    addressQuery: String,
//    onQueryChange: (String) -> Unit,
//    stops: List<StopFields>,
//    addressSuggestions: List<String>,
//    onSuggestionClick: (String) -> Unit,
//    onAddFavorite: (String) -> Unit,
//    onSearchClick: () -> Unit,
//    speechLauncher: ActivityResultLauncher<Intent>,
//    onSearchAddress: Any,
//    isAddressDetected: Boolean
//) {
//    var expanded by remember { mutableStateOf(false) }
//    var isFocused by remember { mutableStateOf(false) }
//
//    val focusRequester = remember { FocusRequester() }
//    val transition = updateTransition(targetState = isFocused, label = "focusTransition")
//
//    // Animations fluides
//    val elevation by transition.animateDp(label = "elevationAnim") {
//        if (it) 10.dp else 4.dp
//    }
//    val yOffset by transition.animateDp(label = "offsetAnim") {
//        if (it) (-4).dp else 0.dp
//    }
//    val scale by transition.animateFloat(label = "scaleAnim") {
//        if (it) 1.02f else 1f
//    }
//
//    val stopSuggestions = stops.map { it.stop_name }.distinct()
//    val allSuggestions = remember(addressQuery, addressSuggestions, stops) {
//        (addressSuggestions + stopSuggestions)
//            .filter { it.contains(addressQuery, ignoreCase = true) }
//            .distinct()
//            .take(8)
//    }
//
//    Column(
//        modifier = Modifier
//            .fillMaxWidth()
//            .padding(horizontal = 12.dp)
//            .offset(y = yOffset)
//            .scale(scale)
//    ) {
//        Card(
//            modifier = Modifier
//                .fillMaxWidth(),
//            shape = RoundedCornerShape(50),
//            elevation = CardDefaults.cardElevation(elevation),
//            colors = CardDefaults.cardColors(containerColor = Color.White),
//        ) {
//            Row(
//                verticalAlignment = Alignment.CenterVertically,
//                modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp)
//            ) {
//                // 🔍 Bouton de recherche
//                IconButton(onClick = onSearchClick) {
//                    Icon(
//                        imageVector = Icons.Default.Search,
//                        contentDescription = "Rechercher",
//                        tint = Color(0xFF4285F4)
//                    )
//                }
//
//                // ✏️ Champ de saisie
//                TextField(
//                    value = addressQuery,
//                    onValueChange = {
//                        onQueryChange(it)
//                        expanded = it.isNotEmpty()
//                    },
//                    placeholder = {
//                        Text(
//                            "Où allons-nous ?",
//                            color = Color.Gray
//                        )
//                    },
//                    modifier = Modifier
//                        .weight(1f)
//                        .focusRequester(focusRequester)
//                        .onFocusChanged { focusState ->
//                            isFocused = focusState.isFocused
//                        },
//                    colors = TextFieldDefaults.colors(
//                        focusedContainerColor = Color.Transparent,
//                        unfocusedContainerColor = Color.Transparent,
//                        focusedIndicatorColor = Color.Transparent,
//                        unfocusedIndicatorColor = Color.Transparent,
//                        cursorColor = Color(0xFF4285F4)
//                    ),
//                    textStyle = LocalTextStyle.current.copy(fontSize = 16.sp),
//                    singleLine = true
//                )
//                if (isAddressDetected) {
//                    Icon(
//                        imageVector = Icons.Default.Add, // ou Icons.Default.Check si tu veux un check vert
//                        contentDescription = "Adresse trouvée",
//                        tint = Color(0xFF4CAF50), // Vert “succès”
//                        modifier = Modifier
//                            .size(26.dp)
//                            .padding(start = 4.dp)
//                    )
//                }
//
////                // 🎙 Micro
////                IconButton(onClick = { speechLauncher.launch(getSpeechIntent()) }) {
////                    Icon(
////                        imageVector = Icons.Default.Mic,
////                        contentDescription = "Micro",
////                        tint = Color(0xFF4285F4)
////                    )
////                }
//
//                // ⭐ Favoris + ❌ effacer
//                if (addressQuery.isNotEmpty()) {
//                    IconButton(onClick = { onAddFavorite(addressQuery) }) {
//                        Icon(
//                            imageVector = Icons.Default.Star,
//                            contentDescription = "Favori",
//                            tint = Color(0xFF4285F4)
//                        )
//                    }
//                    IconButton(onClick = { onQueryChange("") }) {
//                        Icon(
//                            imageVector = Icons.Default.Close,
//                            contentDescription = "Effacer",
//                            tint = Color(0xFF4285F4)
//                        )
//                    }
//                }
//            }
//        }
//
//        // 🔽 Menu déroulant animé
//        AnimatedVisibility(
//            visible = expanded && allSuggestions.isNotEmpty(),
//            enter = fadeIn() + expandVertically(),
//            exit = fadeOut() + shrinkVertically()
//        ) {
//            Card(
//                modifier = Modifier
//                    .fillMaxWidth()
//                    .padding(horizontal = 8.dp)
//                    .shadow(8.dp, RoundedCornerShape(16.dp)),
//                shape = RoundedCornerShape(16.dp),
//                colors = CardDefaults.cardColors(containerColor = Color.White)
//            ) {
//                Column {
//                    allSuggestions.forEach { suggestion ->
//                        DropdownMenuItem(
//                            leadingIcon = {
//                                Icon(
//                                    imageVector = if (stops.any { it.stop_name == suggestion })
//                                        Icons.Default.DirectionsBus else Icons.Default.Place,
//                                    contentDescription = null,
//                                    tint = if (stops.any { it.stop_name == suggestion })
//                                        MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary
//                                )
//                            },
//                            text = { Text(suggestion) },
//                            onClick = {
//                                onSuggestionClick(suggestion)
//                                expanded = false
//                            }
//                        )
//                    }
//                }
//            }
//        }
//    }
//}


@SuppressLint("MissingPermission")
fun getAddressSuggestions(context: Context, query: String, onResult: (List<String>) -> Unit) {
    if (query.isBlank()) {
        onResult(emptyList())
        return
    }

    val geocoder = Geocoder(context, Locale.getDefault())

    try {
        val addresses = geocoder.getFromLocationName(query, 5)
        if (!addresses.isNullOrEmpty()) {
            val suggestions = addresses.mapNotNull { address ->
                val line = buildString {
                    append(address.getAddressLine(0))
                }
                line
            }
            onResult(suggestions)
        } else {
            onResult(emptyList())
        }
    } catch (e: Exception) {
        e.printStackTrace()
        onResult(emptyList())
    }
}
