import {useParams} from "react-router-dom"
import type {RecipeModel} from "../../models/RecipeModel"
import {useEffect, useState} from "react"
import {fetchRecipe} from "../../api/points/RecipePoint"
import {getRecipeEditUrl, getRecipeListUrl} from "../../routes"
import ButtonLink from "../basics/ButtonLink"
import {mapRecipeDtoToModel} from "../../mappers/RecipeMapper"
import {NumberStepControl} from "../basics/NumberStepControl.tsx";
import {NumberedListItem} from "../basics/NumberedListItem.tsx";
import {ButtonType} from "../basics/BasicButtonDefinitions.ts";
import StickyHeader from "../basics/StickyHeader.tsx";
import ButtonGroupLayout from "../basics/ButtonGroupLayout.tsx";
import ContentBody from "../basics/ContentBody.tsx";
import PageContainer from "../basics/PageContainer.tsx";
import {BoxContainer} from "../basics/BoxContainer.tsx";
import IngredientGroupDisplayListItem from "./IngredientGroupDisplayListItem.tsx";
import PageContentLayout from "../basics/PageContentLayout.tsx";


/**
 * Displays the full detail of a single recipe,
 * including its ingredients, instructions, and image.
 */
export default function RecipeDetailPage() {
    // Extract recipe ID from route params
    const {id} = useParams<{ id: string }>()
    // the recipe loaded from the backend, don't change this! it's required for scaling
    const [recipe, setRecipe] = useState<RecipeModel | null>(null)
    // Working copy for re-calculating ingredients
    const [recipeWorkingCopy, setRecipeWorkingCopy] = useState<RecipeModel | null>(null)
    // load recipe data whenever id changes
    useEffect(() => {
        const loadRecipe = async () => {
            if (id) {
                // Fetch recipe data when editing an existing one
                console.log("loading recipe with id", id)
                const data = await fetchRecipe(id)
                if (data.id != id) {
                    throw new Error("Id mismatch when loading recipes: " + id + " requested and " + data.id + " received!");
                }
                setRecipe(mapRecipeDtoToModel(data))
            }
        }

        loadRecipe()
    }, [id])

    // set original recipe data and working copy when recipe changes
    useEffect(() => {
        setRecipeWorkingCopy(recipe);
    }, [recipe])


    if (!recipe || !recipeWorkingCopy) {
        return <p className="p-6">Recipe not found.</p>
    }


    /** recalculate ingredients based on the amount of servings */
    const recalculateIngredients = (newAmount: number) => {
        // Always calculate factor from the *original recipe*, not the working copy
        const factor = newAmount / recipe.servings.amount

        // Create a new ingredient list with updated amounts
        const updatedIngredientGroupList = recipe.ingredientGroupList.map((ingGrp) => ({
            ...ingGrp,
            ingredientList: ingGrp.ingredientList.map((ing) => ({
                ...ing,
                // ensure only to recalculate the amount of ingredients that actually have an amout...
                amount: (ing.amount) ? ing.amount * factor : undefined,
            }))
        }))

        // Update working copy with new servings + recalculated ingredients
        setRecipeWorkingCopy({
            ...recipeWorkingCopy,
            servings: {
                ...recipeWorkingCopy.servings,
                amount: newAmount,
            },
            ingredientGroupList: updatedIngredientGroupList,
        })
    }

    return (
        /*Container spanning entire screen used to center content horizontally */
        <PageContainer>
            {/* Container defining the maximum width of the content */}
            <PageContentLayout>
                {/* Header - remains in position when scrolling */}
                <StickyHeader>
                    <h1>{recipeWorkingCopy.title}</h1>
                </StickyHeader>

                {/* Content */}
                <ContentBody>
                    {/* Recipe image */}
                    {recipe.imageUrl && (
                        <img
                            src={recipe.imageUrl}
                            alt={recipe.title}
                            className="w-full rounded-xl mb-4 border"
                        />
                    )}

                    {/* Servings */}
                    <BoxContainer
                        className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-4">
                        <p>
                            Für {recipeWorkingCopy.servings.amount} {recipeWorkingCopy.servings.unit}
                        </p>

                        <NumberStepControl
                            value={recipeWorkingCopy.servings.amount}
                            onChange={recalculateIngredients}
                            min={1}
                            className="justify-end sm:justify-center"
                        />
                    </BoxContainer>

                    {/* Ingredients */}
                    <h2>Zutaten</h2>
                    <ul>
                        {recipeWorkingCopy.ingredientGroupList.map((group, i) => (
                            <IngredientGroupDisplayListItem
                                key={i}
                                index={i}
                                groupModel={group}
                            />
                        ))}
                    </ul>

                    {/* Instructions */}
                    <h2>Zubereitung</h2>
                    <ol className="space-y-4">
                        {recipe.instructionStepList.map((step, j) => (
                            <NumberedListItem key={j} index={j} text={step.text}/>
                        ))}
                    </ol>

                    {/* Action buttons */}
                    <ButtonGroupLayout>
                        <ButtonLink
                            to={recipe.id !== undefined ? getRecipeEditUrl(recipe.id) : getRecipeListUrl()} // @todo show error instead
                            buttonType={ButtonType.PrimaryButton}
                            text="Bearbeiten"
                        />
                        <ButtonLink
                            to={getRecipeListUrl()}
                            text="Zurueck"
                        />
                    </ButtonGroupLayout>
                </ContentBody>
            </PageContentLayout>
        </PageContainer>
    )
}
