package dev.adriankuta.flights.ui.home

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.PreviewParameter
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.Flight
import dev.adriankuta.flights.domain.types.RegularFare
import dev.adriankuta.flights.domain.types.Segment
import dev.adriankuta.flights.domain.types.Trip
import dev.adriankuta.flights.domain.types.TripDate
import dev.adriankuta.flights.domain.types.TripFare
import dev.adriankuta.flights.domain.types.TripFlight
import dev.adriankuta.flights.ui.designsystem.theme.FlightsTheme
import dev.adriankuta.flights.ui.designsystem.theme.PreviewDevices
import dev.adriankuta.flights.ui.home.components.SearchForm
import dev.adriankuta.flights.ui.home.components.SearchResults
import dev.adriankuta.flights.ui.home.sample.HomeUiStatePreviewParameterProvider
import kotlinx.datetime.LocalDate

@Composable
internal fun HomeScreen(
    viewModel: HomeScreenViewModel = hiltViewModel(),
) {
    val homeUiState by viewModel.uiState.collectAsStateWithLifecycle()
    val searchResults by viewModel.searchResultUiState.collectAsStateWithLifecycle()

    HomeScreen(
        uiState = homeUiState,
        searchResultsUiState = searchResults,
        onOriginAirportSelect = viewModel::selectOriginAirport,
        onDestinationAirportSelect = viewModel::selectDestinationAirport,
        onDateSelect = viewModel::selectDate,
        onAdultCountChange = viewModel::updateAdultCount,
        onTeenCountChange = viewModel::updateTeenCount,
        onChildCountChange = viewModel::updateChildCount,
        onSearch = viewModel::search,
    )
}

@Composable
private fun HomeScreen(
    uiState: HomeUiState,
    searchResultsUiState: SearchResultUiState,
    onOriginAirportSelect: (AirportInfo) -> Unit,
    onDestinationAirportSelect: (AirportInfo) -> Unit,
    onDateSelect: (LocalDate) -> Unit,
    onAdultCountChange: (Int) -> Unit,
    onTeenCountChange: (Int) -> Unit,
    onChildCountChange: (Int) -> Unit,
    onSearch: () -> Unit,
    modifier: Modifier = Modifier,
) {
    var showSearchResults by rememberSaveable { mutableStateOf(false) }

    BackHandler(enabled = showSearchResults) {
        showSearchResults = false
    }

    Box(
        modifier = modifier
            .padding(16.dp),
    ) {
        when (uiState) {
            is HomeUiState.Error -> Text("Error")
            HomeUiState.Loading -> Text("Loading")
            is HomeUiState.Success -> if (showSearchResults) {
                SearchResults(
                    uiState = searchResultsUiState,
                )
            } else {
                SearchForm(
                    uiState = uiState,
                    onOriginAirportSelect = onOriginAirportSelect,
                    onDestinationAirportSelect = onDestinationAirportSelect,
                    onDateSelect = onDateSelect,
                    onAdultCountChange = onAdultCountChange,
                    onTeenCountChange = onTeenCountChange,
                    onChildCountChange = onChildCountChange,
                    onSearch = {
                        showSearchResults = true
                        onSearch()
                    },
                    modifier = Modifier.verticalScroll(rememberScrollState()),
                )
            }
        }
    }
}

@PreviewDevices
@Composable
private fun HomeScreenLoadingPreview() {
    FlightsTheme {
        HomeScreen(
            uiState = HomeUiState.Loading,
            searchResultsUiState = SearchResultUiState.Idle,
            onOriginAirportSelect = {},
            onDestinationAirportSelect = {},
            onDateSelect = {},
            onAdultCountChange = {},
            onTeenCountChange = {},
            onChildCountChange = {},
            onSearch = {},
        )
    }
}

@PreviewDevices
@Composable
private fun HomeScreenSuccessPreview(
    @PreviewParameter(HomeUiStatePreviewParameterProvider::class) homeUiState: HomeUiState,
) {
    FlightsTheme {
        HomeScreen(
            uiState = homeUiState,
            searchResultsUiState = SearchResultUiState.Idle,
            onOriginAirportSelect = {},
            onDestinationAirportSelect = {},
            onDateSelect = {},
            onAdultCountChange = {},
            onTeenCountChange = {},
            onChildCountChange = {},
            onSearch = {},
        )
    }
}

@PreviewDevices
@Composable
@Suppress("LongMethod")
private fun HomeScreenSearchResultsPreview(
    @PreviewParameter(HomeUiStatePreviewParameterProvider::class) homeUiState: HomeUiState,
) {
    val mockFlight = Flight(
        currency = "PLN",
        currPrecision = 2,
        trips = listOf<Trip>(
            Trip(
                origin = "WAW",
                destination = "KRK",
                dates = listOf<TripDate>(
                    TripDate(
                        dateOut = LocalDate(2023, 6, 15),
                        flights = listOf(
                            TripFlight(
                                faresLeft = 10,
                                regularFare = RegularFare(
                                    fares = listOf(
                                        TripFare(
                                            type = "ADT",
                                            amount = 150.0,
                                            count = 1,
                                        ),
                                    ),
                                ),
                                flightNumber = "FR1234",
                                dateTimes = listOf(
                                    "2023-06-15T10:00:00",
                                    "2023-06-15T11:30:00",
                                ),
                                duration = "1h 30m",
                                segments = listOf(
                                    Segment(
                                        origin = "WAW",
                                        destination = "KRK",
                                        flightNumber = "FR1234",
                                        dateTimes = listOf(
                                            "2023-06-15T10:00:00",
                                            "2023-06-15T11:30:00",
                                        ),
                                        duration = "1h 30m",
                                    ),
                                ),
                                operatedBy = "Ryanair",
                            ),
                        ),
                    ),
                ),
            ),
        ),
    )

    FlightsTheme {
        HomeScreen(
            uiState = homeUiState,
            searchResultsUiState = SearchResultUiState.Success(mockFlight),
            onOriginAirportSelect = {},
            onDestinationAirportSelect = {},
            onDateSelect = {},
            onAdultCountChange = {},
            onTeenCountChange = {},
            onChildCountChange = {},
            onSearch = {},
        )
    }
}
