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

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.composeunstyled.UnstyledButton
import dev.ulfrx.recipe.ui.components.recipe.IngredientCard
import dev.ulfrx.recipe.ui.components.recipe.IngredientDivider
import dev.ulfrx.recipe.ui.components.recipe.IngredientRow
import dev.ulfrx.recipe.ui.components.recipe.RecipeIngredientOptionUi
import dev.ulfrx.recipe.ui.components.recipe.RecipeIngredientSlotUi
import dev.ulfrx.recipe.ui.components.recipe.scaledBy
import dev.ulfrx.recipe.ui.theme.RecipeTheme
import org.jetbrains.compose.resources.stringResource
import recipe.composeapp.generated.resources.Res
import recipe.composeapp.generated.resources.meal_plan_editor_removed_format
import recipe.composeapp.generated.resources.meal_plan_editor_removed_restore

/**
 * Wrapping card with one row per visible ingredient — both the recipe's
 * (minus excluded) and the user-added ones — plus the "X usuniętych —
 * Przywróć" bar appended below the card. Reuses the shared [IngredientRow]
 * so the visual language matches the read-only detail screen exactly.
 */
@Composable
internal fun IngredientEditorList(
    recipeIngredients: List<RecipeIngredientSlotUi>,
    addedIngredients: List<AddedIngredientUi>,
    excludedIngredientIds: Set<String>,
    substitutions: Map<String, String>,
    servings: Int,
    onSelectSubstitution: (slotId: String, optionId: String) -> Unit,
    onRemoveRecipeIngredient: (slotId: String) -> Unit,
    onRemoveAddedIngredient: (ingredientId: String) -> Unit,
    onRestoreRemoved: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val visibleRecipeIngredients =
        remember(recipeIngredients, excludedIngredientIds) {
            recipeIngredients.filter { it.id !in excludedIngredientIds }
        }

    Column(modifier = modifier.fillMaxWidth()) {
        IngredientCard {
            visibleRecipeIngredients.forEachIndexed { index, slot ->
                if (index > 0) IngredientDivider()
                val scaledSlot = remember(slot, servings) { slot.scaledBy(servings) }
                IngredientRow(
                    slot = scaledSlot,
                    selectedOptionId = substitutions[slot.id] ?: slot.default.id,
                    onSelect =
                        if (slot.alternatives.isNotEmpty()) {
                            { choice -> onSelectSubstitution(slot.id, choice.id) }
                        } else {
                            null
                        },
                    onRemove = { onRemoveRecipeIngredient(slot.id) },
                )
            }
            addedIngredients.forEachIndexed { index, added ->
                if (visibleRecipeIngredients.isNotEmpty() || index > 0) IngredientDivider()
                val scaledSlot = remember(added, servings) { added.toScaledSyntheticSlot(servings) }
                IngredientRow(
                    slot = scaledSlot,
                    addedMarker = true,
                    onRemove = { onRemoveAddedIngredient(added.ingredientId) },
                )
            }
        }

        if (excludedIngredientIds.isNotEmpty()) {
            RemovedBar(
                count = excludedIngredientIds.size,
                onRestore = onRestoreRemoved,
                modifier = Modifier.padding(top = RecipeTheme.spacing.sm),
            )
        }
    }
}

@Composable
private fun RemovedBar(
    count: Int,
    onRestore: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val colors = RecipeTheme.colors
    Row(
        modifier =
            modifier
                .fillMaxWidth()
                .padding(horizontal = RemovedBarHorizontalInset),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween,
    ) {
        BasicText(
            text = stringResource(Res.string.meal_plan_editor_removed_format, count),
            style =
                RecipeTheme.typography.label.copy(
                    color = colors.contentMuted,
                    fontSize = RemovedBarTextSize,
                ),
        )
        UnstyledButton(
            onClick = onRestore,
            contentColor = colors.content,
            backgroundColor = Color.Transparent,
        ) {
            BasicText(
                text = stringResource(Res.string.meal_plan_editor_removed_restore),
                style =
                    RecipeTheme.typography.label.copy(
                        color = colors.content,
                        fontWeight = FontWeight.SemiBold,
                        fontSize = RemovedBarTextSize,
                    ),
            )
        }
    }
}

private fun AddedIngredientUi.toScaledSyntheticSlot(servings: Int): RecipeIngredientSlotUi =
    RecipeIngredientSlotUi(
        default =
            RecipeIngredientOptionUi(
                id = ingredientId,
                name = name,
                amount = amount * servings,
                unit = unit,
            ),
        alternatives = emptyList(),
        id = "added:$ingredientId",
    )

private val RemovedBarHorizontalInset = 4.dp
private val RemovedBarTextSize = 11.sp
