package com.pixelized.headache.ui.page.event.list

import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.pixelized.headache.R
import com.pixelized.headache.ui.common.toolbar.Toolbar
import com.pixelized.headache.ui.navigation.main.LocalMainNavigator
import com.pixelized.headache.ui.page.event.edit.EventEditBottomSheet
import com.pixelized.headache.ui.page.event.edit.EventEditBottomSheetViewModel
import com.pixelized.headache.ui.theme.HeadacheTheme
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
import java.util.Date

@Stable
data object EventPageDefault {
    @Stable
    val listPadding: PaddingValues = PaddingValues(bottom = 56.dp + 16.dp * 2)

    @Stable
    val spacing: Dp = 0.dp
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EventPage(
    viewModel: EventViewModel = hiltViewModel(),
    editViewModel: EventEditBottomSheetViewModel = hiltViewModel(),
) {
    val navigation = LocalMainNavigator.current
    val events = viewModel.events.collectAsStateWithLifecycle()
    val misspelledFilter = viewModel.misspelledFilter.collectAsStateWithLifecycle()
    val invalidFilter = viewModel.invalidFilter.collectAsStateWithLifecycle()

    EventContent(
        modifier = Modifier.fillMaxSize(),
        misspelledFilter = misspelledFilter,
        invalidFilter = invalidFilter,
        events = events,
        onBack = { navigation.popBackstack() },
        onMisspelledFilter = viewModel::toggleMisspelledFilter,
        onInvalidFilter = viewModel::toggleErrorFilter,
        onAddEvent = { editViewModel.show() },
        onEvent = { editViewModel.show(eventId = it.id) }
    )

    EventEditBottomSheet(
        viewModel = editViewModel,
        onDismissRequest = { editViewModel.dismiss() },
    )
}

@Composable
@OptIn(ExperimentalMaterial3Api::class)
private fun EventContent(
    modifier: Modifier = Modifier,
    listPadding: PaddingValues = EventPageDefault.listPadding,
    spacing: Dp = EventPageDefault.spacing,
    invalidFilter: State<Boolean>,
    misspelledFilter: State<Boolean>,
    events: State<List<EventItemUio>>,
    onBack: () -> Unit,
    onInvalidFilter: () -> Unit,
    onMisspelledFilter: () -> Unit,
    onAddEvent: () -> Unit,
    onEvent: (EventItemUio) -> Unit,
) {
    Scaffold(
        modifier = modifier,
        topBar = {
            Toolbar(
                navigationIcon = {
                    IconButton(
                        onClick = onBack,
                    ) {
                        Icon(
                            imageVector = Icons.AutoMirrored.Filled.ArrowBack,
                            contentDescription = null,
                        )
                    }
                },
                title = {
                    Text(
                        text = stringResource(R.string.event_title),
                    )
                },
                actions = {
                    IconButton(
                        onClick = onMisspelledFilter,
                    ) {
                        val color = animateColorAsState(
                            when (misspelledFilter.value) {
                                true -> MaterialTheme.colorScheme.error
                                else -> MaterialTheme.colorScheme.onSurface
                            }
                        )
                        Icon(
                            painter = painterResource(R.drawable.ic_spellcheck_24px),
                            tint = color.value,
                            contentDescription = null,
                        )
                    }

                    IconButton(
                        onClick = onInvalidFilter,
                    ) {
                        val color = animateColorAsState(
                            when (invalidFilter.value) {
                                true -> MaterialTheme.colorScheme.error
                                else -> MaterialTheme.colorScheme.onSurface
                            }
                        )
                        Icon(
                            imageVector = Icons.Outlined.Info,
                            tint = color.value,
                            contentDescription = null,
                        )
                    }
                }
            )
        },
        floatingActionButton = {
            FloatingActionButton(
                containerColor = MaterialTheme.colorScheme.primary,
                shape = CircleShape,
                onClick = onAddEvent,
            ) {
                Icon(
                    imageVector = Icons.Default.Add,
                    contentDescription = null,
                )
            }
        },
        content = { paddingValues ->
            LazyColumn(
                modifier = Modifier
                    .padding(paddingValues = paddingValues)
                    .fillMaxSize(),
                verticalArrangement = Arrangement.spacedBy(space = spacing),
                contentPadding = listPadding,
            ) {
                items(
                    items = events.value,
                    key = { it.id },
                    contentType = { "EventItem" },
                ) { item ->
                    EventItem(
                        item = item,
                        onItem = onEvent,
                    )
                }
            }
        }
    )
}

@Composable
@Preview
private fun EventContentPreview(
    @PreviewParameter(EventContentPreviewProvider::class) preview: List<EventItemUio>,
) {
    HeadacheTheme {
        Surface {
            EventContent(
                invalidFilter = remember { mutableStateOf(false) },
                misspelledFilter = remember { mutableStateOf(false) },
                events = remember { mutableStateOf(preview) },
                onBack = { },
                onInvalidFilter = { },
                onMisspelledFilter = { },
                onAddEvent = { },
                onEvent = { },
            )
        }
    }
}

private class EventContentPreviewProvider : PreviewParameterProvider<List<EventItemUio>> {
    override val values: Sequence<List<EventItemUio>>
        get() = sequenceOf(
            listOf(
                EventItemUio(
                    id = 0,
                    date = Date(),
                    pills = emptyList(),
                    isValid = true,
                    isMisspelled = false,
                ),
                EventItemUio(
                    id = 1,
                    date = Date(),
                    pills = listOf(
                        PillUio(
                            label = "Spifen 400",
                            amount = 1,
                            description = "Spifen 400",
                            color = HeadacheColorPalette.Additional.Yellow,
                            isValid = true,
                            isMisspelled = false,
                        ),
                        PillUio(
                            label = "Élétriptan 40",
                            amount = 1,
                            description = "Élitriptan 40",
                            color = HeadacheColorPalette.Additional.Purple,
                            isValid = true,
                            isMisspelled = true,
                        ),
                    ),
                    isValid = true,
                    isMisspelled = false,
                ),
            ),
        )
}