package dev.adriankuta.flights.ui.home

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.adriankuta.flights.domain.types.AirportInfo
import dev.adriankuta.flights.domain.types.Country
import dev.adriankuta.flights.ui.home.components.AirportInfoCompact
import dev.adriankuta.flights.ui.home.components.AirportInfoItem
import dev.adriankuta.flights.ui.home.components.CountryItem
import dev.adriankuta.flights.ui.stations.R

@Composable
internal fun StationsScreen(
    stationScreenViewModel: StationsScreenViewModel = hiltViewModel(),
) {
    val originAirports by stationScreenViewModel.originAirports.collectAsStateWithLifecycle()
    val searchQuery by stationScreenViewModel.searchQuery.collectAsStateWithLifecycle()
    val selectedOriginAirport by stationScreenViewModel.selectedOriginAirport.collectAsStateWithLifecycle()

    BackHandler(selectedOriginAirport != null) {
        stationScreenViewModel.clearSelectedAirport()
    }

    StationsScreen(
        originAirports = originAirports,
        searchQuery = searchQuery,
        selectedOriginAirport = selectedOriginAirport,
        onSearchQueryChang = stationScreenViewModel::onSearchQueryChanged,
        onAirportSelect = stationScreenViewModel::onAirportSelected,
    )
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun StationsScreen(
    originAirports: AirportsUiState,
    searchQuery: String,
    selectedOriginAirport: AirportInfo?,
    onSearchQueryChang: (String) -> Unit,
    onAirportSelect: (AirportInfo) -> Unit,
) {
    Column(
        modifier = Modifier.fillMaxWidth(),
    ) {
        AnimatedVisibility(selectedOriginAirport != null) {
            var airportInfo by remember { mutableStateOf(selectedOriginAirport!!) }
            LaunchedEffect(selectedOriginAirport) {
                selectedOriginAirport?.let { airportInfo = it }
            }
            AirportInfoCompact(
                data = airportInfo,
            )
        }

        OutlinedTextField(
            value = searchQuery,
            onValueChange = onSearchQueryChang,
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            placeholder = { Text(text = stringResource(R.string.search_airports)) },
            leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
            singleLine = true,
        )

        LazyColumn(
            modifier = Modifier.fillMaxWidth(),
        ) {
            when (originAirports) {
                is AirportsUiState.Error -> item { Text("Error") }
                is AirportsUiState.Loading -> item { Text("Loading") }
                is AirportsUiState.Success -> groupedAirports(
                    data = originAirports.groupedAirports,
                    onAirportSelected = onAirportSelect,
                )
            }
        }
    }
}

private fun LazyListScope.groupedAirports(
    data: Map<Country, List<AirportInfo>>,
    onAirportSelected: (AirportInfo) -> Unit,
) {
    data.keys.forEach { country ->
        stickyHeader {
            key(country.code) {
                CountryItem(data = country, modifier = Modifier.animateItem())
            }
        }
        items(data[country]!!) { airport ->
            key(airport.code) {
                AirportInfoItem(
                    data = airport,
                    modifier = Modifier.animateItem(),
                    onClick = onAirportSelected,
                )
            }
        }
    }
}
