package id.iiyh.inatrading.feature.profile.presentation

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.os.Build
import android.os.CancellationSignal
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.KeyboardArrowDown
import androidx.compose.material.icons.outlined.LocationOn
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import id.iiyh.inatrading.R
import id.iiyh.inatrading.core.ui.theme.BrandRed
import id.iiyh.inatrading.core.ui.theme.OnSurface
import id.iiyh.inatrading.core.ui.theme.OnSurfaceVariant
import id.iiyh.inatrading.core.ui.theme.SurfaceContainerHighest
import id.iiyh.inatrading.core.ui.theme.SurfaceContainerLow
import id.iiyh.inatrading.core.ui.theme.SurfaceContainerLowest
import androidx.compose.ui.window.Dialog

data class DropdownOption(
    val id: String,
    val label: String,
)

@Composable
fun AddressDropdownField(
    value: String,
    label: String,
    placeholder: String,
    options: List<DropdownOption>,
    enabled: Boolean = true,
    onOptionSelected: (DropdownOption) -> Unit,
) {
    var dialogOpen by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(
                enabled = enabled,
                interactionSource = remember { MutableInteractionSource() },
                indication = null,
                onClick = { dialogOpen = true },
            ),
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            Text(
                text = label,
                style = MaterialTheme.typography.bodySmall,
                color = OnSurfaceVariant,
                modifier = Modifier.padding(start = 16.dp, bottom = 6.dp),
            )
            Surface(
                modifier = Modifier.fillMaxWidth(),
                shape = RoundedCornerShape(16.dp),
                color = SurfaceContainerLow,
                tonalElevation = 0.dp,
            ) {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(horizontal = 16.dp, vertical = 16.dp),
                    verticalAlignment = androidx.compose.ui.Alignment.CenterVertically,
                ) {
                    Text(
                        text = value.ifBlank { placeholder },
                        style = MaterialTheme.typography.bodyLarge,
                        color = if (value.isBlank()) {
                            OnSurfaceVariant.copy(alpha = 0.65f)
                        } else {
                            OnSurface
                        },
                        modifier = Modifier.weight(1f),
                    )
                    Spacer(modifier = Modifier.width(12.dp))
                    Icon(
                        imageVector = Icons.Outlined.KeyboardArrowDown,
                        contentDescription = null,
                        tint = OnSurfaceVariant,
                    )
                }
            }
        }
    }

    if (dialogOpen) {
        Dialog(onDismissRequest = { dialogOpen = false }) {
            Surface(
                modifier = Modifier.fillMaxWidth(),
                shape = RoundedCornerShape(24.dp),
                color = SurfaceContainerLowest,
                tonalElevation = 4.dp,
                shadowElevation = 12.dp,
            ) {
                Column(
                    modifier = Modifier.padding(vertical = 12.dp),
                ) {
                    Text(
                        text = label,
                        style = MaterialTheme.typography.titleMedium,
                        color = OnSurface,
                        modifier = Modifier.padding(horizontal = 20.dp, vertical = 8.dp),
                    )
                    Column(
                        modifier = Modifier
                            .heightIn(max = 360.dp)
                            .verticalScroll(rememberScrollState()),
                    ) {
                        options.forEach { option ->
                            Row(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .clickable {
                                        dialogOpen = false
                                        onOptionSelected(option)
                                    }
                                    .padding(horizontal = 20.dp, vertical = 16.dp),
                                verticalAlignment = androidx.compose.ui.Alignment.CenterVertically,
                            ) {
                                Text(
                                    text = option.label,
                                    maxLines = 1,
                                    overflow = TextOverflow.Ellipsis,
                                    style = MaterialTheme.typography.bodyLarge,
                                    color = OnSurface,
                                )
                            }
                        }
                    }
                }
            }
        }
    }
}

@Composable
fun CurrentLocationPermissionMessage() {
    val context = LocalContext.current
    Box(
        modifier = Modifier.padding(top = 6.dp),
    ) {
        Text(
            text = if (hasLocationPermission(context)) {
                stringResource(R.string.address_pin_helper_ready)
            } else {
                stringResource(R.string.address_pin_helper_permission)
            },
            style = MaterialTheme.typography.bodySmall,
            color = OnSurfaceVariant,
        )
    }
}

@Composable
fun AddressPinTeaser(
    latitude: Double?,
    longitude: Double?,
    isLoading: Boolean = false,
    onClick: () -> Unit,
) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(132.dp)
            .background(
                brush = androidx.compose.ui.graphics.Brush.linearGradient(
                    colors = listOf(
                        SurfaceContainerHighest,
                        SurfaceContainerLow,
                        SurfaceContainerLowest,
                    )
                ),
                shape = RoundedCornerShape(20.dp),
            )
            .clickable(
                enabled = !isLoading,
                interactionSource = remember { MutableInteractionSource() },
                indication = androidx.compose.material3.ripple(),
                onClick = onClick,
            ),
    ) {
        Row(
            modifier = Modifier
                .align(androidx.compose.ui.Alignment.Center)
                .background(Color.White.copy(alpha = 0.92f), CircleShape)
                .padding(horizontal = 18.dp, vertical = 10.dp),
            verticalAlignment = androidx.compose.ui.Alignment.CenterVertically,
            horizontalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy(8.dp),
        ) {
            if (isLoading) {
                CircularProgressIndicator(
                    modifier = Modifier.size(18.dp),
                    color = BrandRed,
                    strokeWidth = 2.dp,
                )
            } else {
                Icon(
                    imageVector = Icons.Outlined.LocationOn,
                    contentDescription = null,
                    tint = BrandRed,
                    modifier = Modifier.size(20.dp),
                )
            }
            Text(
                text = if (isLoading) {
                    stringResource(R.string.address_pin_loading)
                } else if (latitude != null && longitude != null) {
                    stringResource(R.string.address_pin_coordinates, latitude, longitude)
                } else {
                    stringResource(R.string.add_shipping_address_pin)
                },
                fontWeight = androidx.compose.ui.text.font.FontWeight.Bold,
                color = OnSurface,
            )
        }
    }
}

fun hasLocationPermission(context: Context): Boolean {
    val fine = ContextCompat.checkSelfPermission(
        context,
        Manifest.permission.ACCESS_FINE_LOCATION,
    ) == PackageManager.PERMISSION_GRANTED
    val coarse = ContextCompat.checkSelfPermission(
        context,
        Manifest.permission.ACCESS_COARSE_LOCATION,
    ) == PackageManager.PERMISSION_GRANTED
    return fine || coarse
}

@SuppressLint("MissingPermission")
fun requestCurrentLocation(
    context: Context,
    onSuccess: (latitude: Double, longitude: Double) -> Unit,
    onError: (String) -> Unit,
) {
    if (!hasLocationPermission(context)) {
        onError(context.getString(R.string.address_pin_permission_required))
        return
    }

    val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as? LocationManager
        ?: run {
            onError(context.getString(R.string.address_pin_unavailable))
            return
        }

    val providers = locationManager.getProviders(true)
    if (providers.isEmpty()) {
        onError(context.getString(R.string.address_pin_enable_location))
        return
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        val provider = when {
            providers.contains(LocationManager.GPS_PROVIDER) -> LocationManager.GPS_PROVIDER
            providers.contains(LocationManager.NETWORK_PROVIDER) -> LocationManager.NETWORK_PROVIDER
            else -> providers.first()
        }
        locationManager.getCurrentLocation(
            provider,
            CancellationSignal(),
            ContextCompat.getMainExecutor(context),
        ) { location ->
            if (location != null) {
                onSuccess(location.latitude, location.longitude)
            } else {
                emitLastKnownLocation(locationManager, providers, onSuccess, onError, context)
            }
        }
    } else {
        emitLastKnownLocation(locationManager, providers, onSuccess, onError, context)
    }
}

private fun emitLastKnownLocation(
    locationManager: LocationManager,
    providers: List<String>,
    onSuccess: (latitude: Double, longitude: Double) -> Unit,
    onError: (String) -> Unit,
    context: Context,
) {
    val location = providers
        .mapNotNull { provider -> runCatching { locationManager.getLastKnownLocation(provider) }.getOrNull() }
        .maxByOrNull(Location::getTime)

    if (location != null) {
        onSuccess(location.latitude, location.longitude)
    } else {
        onError(context.getString(R.string.address_pin_location_not_found))
    }
}
