package dev.ulfrx.recipe.ui.screens.mealplaneditor

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import dev.ulfrx.recipe.ui.components.calendar.CalendarPillExpandDirection
import dev.ulfrx.recipe.ui.components.calendar.RecipeCalendarPill
import dev.ulfrx.recipe.ui.components.recipe.MealSlot
import dev.ulfrx.recipe.ui.components.recipe.NutritionSummary
import dev.ulfrx.recipe.ui.components.recipe.RecipeServingsStepper
import dev.ulfrx.recipe.ui.components.recipe.scaledBy
import dev.ulfrx.recipe.ui.components.section.SectionTitle
import dev.ulfrx.recipe.ui.keyboard.rememberKeyboardTransitionState
import dev.ulfrx.recipe.ui.theme.RecipeTheme
import kotlinx.datetime.LocalDate
import org.jetbrains.compose.resources.stringResource
import recipe.composeapp.generated.resources.Res
import recipe.composeapp.generated.resources.meal_plan_editor_title
import recipe.composeapp.generated.resources.meal_plan_editor_section_ingredients
import recipe.composeapp.generated.resources.meal_plan_editor_section_servings
import recipe.composeapp.generated.resources.meal_plan_editor_section_slot
import recipe.composeapp.generated.resources.nutrition_label
import recipe.composeapp.generated.resources.recipe_detail_servings_decrement_a11y
import recipe.composeapp.generated.resources.recipe_detail_servings_increment_a11y

@Composable
internal fun MealPlanEditorContent(
    editing: MealPlanEditorState.Editing,
    catalog: List<AddableIngredientUi>,
    topChromeInset: Dp,
    topChromeHeight: Dp,
    onSelectDate: (LocalDate) -> Unit,
    onSetCalendarExpanded: (Boolean) -> Unit,
    onSelectSlot: (MealSlot) -> Unit,
    onSetServings: (Int) -> Unit,
    onSelectSubstitution: (slotId: String, optionId: String) -> Unit,
    onRemoveRecipeIngredient: (slotId: String) -> Unit,
    onRemoveAddedIngredient: (ingredientId: String) -> Unit,
    onRestoreRemoved: () -> Unit,
    onAddIngredient: (AddableIngredientUi) -> Unit,
    modifier: Modifier = Modifier,
) {
    val spacing = RecipeTheme.spacing
    val scrollState = rememberScrollState()
    var addPanelOpen by rememberSaveable { mutableStateOf(false) }
    val navigationInset = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
    val keyboardTransition = rememberKeyboardTransitionState()

    val keyboardReserve =
        when {
            addPanelOpen -> maxOf(keyboardTransition.currentInset, keyboardTransition.targetInset)
            keyboardTransition.currentInset > navigationInset -> keyboardTransition.currentInset
            else -> 0.dp
        }
    val bottomInset = maxOf(navigationInset, keyboardReserve)

    val scaledNutrition =
        remember(editing.recipe.nutrition, editing.servings) {
            editing.recipe.nutrition.scaledBy(editing.servings)
        }
    val usedIngredientIds =
        remember(editing.addedIngredients) {
            editing.addedIngredients.mapTo(mutableSetOf()) { it.ingredientId }
        }

    Box(modifier = Modifier.fillMaxSize().background(RecipeTheme.colors.background)) {
        Column(
            modifier =
                modifier
                    .fillMaxSize()
                    .verticalScroll(scrollState, enabled = !addPanelOpen),
        ) {
            Spacer(Modifier.height(topChromeInset))
            // Aligns the title row with the floating back/confirm chrome at
            // scroll=0: same height, padded inside the chrome's circle pills.
            Box(
                modifier =
                    Modifier
                        .fillMaxWidth()
                        .height(topChromeHeight)
                        .padding(horizontal = spacing.lg + topChromeHeight + spacing.sm),
                contentAlignment = Alignment.Center,
            ) {
                RecipeTitle(recipeTitle = editing.recipe.title)
            }
            Spacer(Modifier.height(spacing.xl))
            RecipeCalendarPill(
                selectedDate = editing.selectedDate,
                expanded = editing.calendarExpanded,
                onExpandedChange = onSetCalendarExpanded,
                onSelectDate = onSelectDate,
                onSelectionShift = onSelectDate,
                expandDirection = CalendarPillExpandDirection.Down,
                glass = false,
                tint = RecipeTheme.colors.surface,
                modifier = Modifier.padding(horizontal = spacing.lg),
            )

            SectionContainer {
                SectionTitle(text = stringResource(Res.string.meal_plan_editor_section_slot))
                Spacer(Modifier.height(spacing.sm))
                MealSlotChipsRow(
                    allSlots = MealSlot.entries,
                    allowedSlots = editing.recipe.allowedSlots,
                    selectedSlot = editing.selectedSlot,
                    onSelectSlot = onSelectSlot,
                )
            }

            SectionContainer {
                SectionTitle(text = stringResource(Res.string.nutrition_label))
                Spacer(Modifier.height(spacing.sm))
                NutritionSummary(
                    nutrition = scaledNutrition,
                    modifier = Modifier.fillMaxWidth(),
                )
            }

            SectionContainer {
                ServingsRow(
                    servings = editing.servings,
                    onServingsChange = onSetServings,
                )
            }

            SectionContainer {
                SectionTitle(text = stringResource(Res.string.meal_plan_editor_section_ingredients))
                Spacer(Modifier.height(spacing.sm))
                IngredientEditorList(
                    recipeIngredients = editing.recipe.ingredients,
                    addedIngredients = editing.addedIngredients,
                    excludedIngredientIds = editing.excludedIngredients,
                    substitutions = editing.substitutions,
                    servings = editing.servings,
                    onSelectSubstitution = onSelectSubstitution,
                    onRemoveRecipeIngredient = onRemoveRecipeIngredient,
                    onRemoveAddedIngredient = onRemoveAddedIngredient,
                    onRestoreRemoved = onRestoreRemoved,
                )
                Spacer(Modifier.height(spacing.sm))
                AddIngredientPanel(
                    catalog = catalog,
                    usedIngredientIds = usedIngredientIds,
                    onPick = onAddIngredient,
                    keyboardClearance = keyboardReserve + spacing.sm,
                    autoFocusEnabled = addPanelOpen,
                    keyboardAnimationDurationMillis = keyboardTransition.animationDurationMillis,
                    onOpenChange = { addPanelOpen = it },
                )
            }

            Spacer(Modifier.height(bottomInset + spacing.xxl))
        }
    }
}

@Composable
private fun ServingsRow(
    servings: Int,
    onServingsChange: (Int) -> Unit,
) {
    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween,
    ) {
        SectionTitle(text = stringResource(Res.string.meal_plan_editor_section_servings))
        RecipeServingsStepper(
            servings = servings,
            servingsRange = MIN_PLAN_SERVINGS..MAX_PLAN_SERVINGS,
            decrementContentDescription = stringResource(Res.string.recipe_detail_servings_decrement_a11y),
            incrementContentDescription = stringResource(Res.string.recipe_detail_servings_increment_a11y),
            onServingsChange = onServingsChange,
        )
    }
}

@Composable
private fun SectionContainer(content: @Composable () -> Unit) {
    Column(
        modifier =
            Modifier
                .fillMaxWidth()
                .padding(
                    start = RecipeTheme.spacing.lg,
                    end = RecipeTheme.spacing.lg,
                    top = RecipeTheme.spacing.xl,
                ),
    ) {
        content()
    }
}

@Composable
private fun RecipeTitle(
    recipeTitle: String,
    modifier: Modifier = Modifier,
) {
    Column(
        modifier = modifier,
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
    ) {
        BasicText(
            text = stringResource(Res.string.meal_plan_editor_title),
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
            style =
                RecipeTheme.typography.body.copy(
                    color = RecipeTheme.colors.content,
                    fontWeight = FontWeight.Medium,
                    fontSize = RecipeTitleSize,
                    lineHeight = RecipeTitleLineHeight,
                    textAlign = TextAlign.Center,
            ),
            modifier = Modifier.fillMaxWidth(),
        )
        Spacer(Modifier.height(RecipeTitleGap))
        BasicText(
            text = recipeTitle,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
            style =
                RecipeTheme.typography.body.copy(
                    color = RecipeTheme.colors.contentMuted,
                    fontWeight = FontWeight.Normal,
                    fontSize = RecipeSubtitleSize,
                    lineHeight = RecipeSubtitleLineHeight,
                    textAlign = TextAlign.Center,
                ),
            modifier = Modifier.fillMaxWidth(),
        )
    }
}

private val RecipeTitleSize = 16.sp
private val RecipeTitleLineHeight = 17.sp
private val RecipeTitleGap = 4.dp
private val RecipeSubtitleSize = 11.sp
private val RecipeSubtitleLineHeight = 14.sp
