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

import android.annotation.SuppressLint
import android.icu.text.DateFormat
import android.icu.text.SimpleDateFormat
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.SheetState
import androidx.compose.material3.Snackbar
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.DpSize
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.pixelized.headache.R
import com.pixelized.headache.ui.common.error.HandleErrorMessage
import com.pixelized.headache.ui.theme.HeadacheTheme
import com.pixelized.headache.ui.theme.color.HeadacheColorPalette
import com.pixelized.headache.utils.extention.capitalize
import kotlinx.coroutines.launch
import java.util.Date
import java.util.Locale

@Stable
data class EventEditBottomSheetUio(
    val id: Long?,
    val date: Date,
    val pills: List<EventPillEditUio>,
)

@Stable
data object EventEditDefault {

    @Stable
    val padding: PaddingValues = PaddingValues(horizontal = 16.dp, vertical = 16.dp)

    @Stable
    val spacing: DpSize = DpSize(width = 8.dp, height = 16.dp)

    @SuppressLint("ConstantLocale")
    @Stable
    val formatter = SimpleDateFormat("EEEE dd MMMM yyyy", Locale.getDefault())
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EventEditBottomSheet(
    viewModel: EventEditBottomSheetViewModel = hiltViewModel(),
    snack: SnackbarHostState = remember { SnackbarHostState() },
    sheetState: SheetState = rememberModalBottomSheetState(
        skipPartiallyExpanded = true,
    ),
    onDismissRequest: () -> Unit,
) {
    viewModel.data.value?.let { item ->
        val scope = rememberCoroutineScope()

        ModalBottomSheet(
            sheetState = sheetState,
            onDismissRequest = onDismissRequest,
        ) {
            Box(
                contentAlignment = Alignment.BottomCenter,
            ) {
                EventEditContent(
                    item = item,
                    onAddPill = viewModel::onAddPill,
                    onRemovePill = viewModel::onRemovePill,
                    onDelete = { scope.launch { viewModel.delete() } },
                    onConfirm = { scope.launch { viewModel.confirm() } },
                )
                SnackbarHost(
                    hostState = snack,
                    snackbar = {
                        Snackbar(
                            containerColor = MaterialTheme.colorScheme.error,
                            contentColor = MaterialTheme.colorScheme.onError,
                            actionContentColor = MaterialTheme.colorScheme.onError,
                            snackbarData = it,
                        )
                    }
                )
            }
        }
    }

    HandleErrorMessage(
        snack = snack,
        errors = viewModel.errors
    )
}

@Composable
private fun EventEditContent(
    modifier: Modifier = Modifier,
    padding: PaddingValues = EventEditDefault.padding,
    spacing: DpSize = EventEditDefault.spacing,
    formatter: DateFormat = EventEditDefault.formatter,
    item: EventEditBottomSheetUio,
    onAddPill: (EventPillEditUio) -> Unit,
    onRemovePill: (EventPillEditUio) -> Unit,
    onDelete: () -> Unit,
    onConfirm: () -> Unit,
) {
    Column(
        modifier = Modifier
            .padding(paddingValues = padding)
            .then(other = modifier),
        verticalArrangement = Arrangement.spacedBy(space = spacing.height),
    ) {
        Text(
            style = MaterialTheme.typography.titleLarge,
            text = formatter.format(item.date).capitalize()
        )

        HorizontalDivider()

        LazyColumn(
            modifier = Modifier.weight(weight = 1f, fill = false),
        ) {
            items(
                items = item.pills
            ) {
                EventPillEdit(
                    item = it,
                    onAdd = onAddPill,
                    onRemove = onRemovePill,
                )
            }
        }

        HorizontalDivider()

        Row(
            horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
        ) {
            if (item.id != null) {
                OutlinedButton(
                    modifier = Modifier.weight(1f),
                    onClick = onDelete,
                ) {
                    Text(
                        text = stringResource(R.string.action_delete)
                    )
                }
            }
            Button(
                modifier = Modifier.weight(2f),
                onClick = onConfirm,
            ) {
                Text(
                    text = stringResource(R.string.action_confirm)
                )
            }
        }
    }
}

@Composable
@Preview
private fun EventEditPreview(
    @PreviewParameter(EventEditPreviewPreviewProvider::class) preview: EventEditBottomSheetUio,
) {
    HeadacheTheme {
        Surface {
            val item = remember { mutableStateOf(preview) }
            EventEditContent(
                item = item.value,
                onAddPill = { pill ->
                    item.value = item.value.let { event ->
                        val pills = event.pills.toMutableList()
                        val pillIndex = pills.indexOfFirst { it.id == pill.id }
                        pills[pillIndex] =
                            pills[pillIndex].let { pill -> pill.copy(amount = pill.amount + 1) }
                        event.copy(pills = pills)
                    }
                },
                onRemovePill = { pill ->
                    item.value = item.value.let { event ->
                        val pills = event.pills.toMutableList()
                        val pillIndex = pills.indexOfFirst { it.id == pill.id }
                        pills[pillIndex] =
                            pills[pillIndex].let { pill -> pill.copy(amount = pill.amount - 1) }
                        event.copy(pills = pills)
                    }
                },
                onDelete = { },
                onConfirm = { },
            )
        }
    }
}

private class EventEditPreviewPreviewProvider : PreviewParameterProvider<EventEditBottomSheetUio> {
    override val values: Sequence<EventEditBottomSheetUio>
        get() = sequenceOf(
            EventEditBottomSheetUio(
                id = null,
                date = Date(),
                pills = listOf(
                    EventPillEditUio(
                        id = 0,
                        color = HeadacheColorPalette.Pill.Paracetamol1000,
                        label = "Paracétamol 1000",
                        amount = 0,
                    ),
                    EventPillEditUio(
                        id = 1,
                        color = HeadacheColorPalette.Pill.Ibuprofene400,
                        label = "Ibuprofène 400",
                        amount = 0,
                    ),
                    EventPillEditUio(
                        id = 2,
                        color = HeadacheColorPalette.Pill.Spifen400,
                        label = "Spifen 400",
                        amount = 0,
                    ),
                    EventPillEditUio(
                        id = 3,
                        color = HeadacheColorPalette.Pill.Eletriptan40,
                        label = "Élétriptan 40",
                        amount = 0,
                    ),
                )
            ),
            EventEditBottomSheetUio(
                id = 1,
                date = Date(),
                pills = listOf(
                    EventPillEditUio(
                        id = 0,
                        color = HeadacheColorPalette.Pill.Paracetamol1000,
                        label = "Paracétamol 1000",
                        amount = 0,
                    ),
                    EventPillEditUio(
                        id = 1,
                        color = HeadacheColorPalette.Pill.Ibuprofene400,
                        label = "Ibuprofène 400",
                        amount = 0,
                    ),
                    EventPillEditUio(
                        id = 2,
                        color = HeadacheColorPalette.Pill.Spifen400,
                        label = "Spifen 400",
                        amount = 2,
                    ),
                    EventPillEditUio(
                        id = 3,
                        color = HeadacheColorPalette.Pill.Eletriptan40,
                        label = "Élétriptan 40",
                        amount = 1,
                    ),
                )
            ),
        )
}