import {useState} from "react"
import type {RecipeModel} from "../../models/RecipeModel"
import type {IngredientGroupModel} from "../../models/IngredientGroupModel"
import {IngredientGroupListEditor} from "./IngredientGroupListEditor"
import Button from "../basics/Button"
import {InstructionStepListEditor} from "./InstructionStepListEditor"
import type {InstructionStepModel} from "../../models/InstructionStepModel"
import {ButtonType} from "../basics/BasicButtonDefinitions"
import ButtonGroupLayout from "../basics/ButtonGroupLayout.tsx";
import ContentBody from "../basics/ContentBody.tsx";
import PageContainer from "../basics/PageContainer.tsx";
import PageContentLayout from "../basics/PageContentLayout.tsx";

type RecipeEditorProps = {
    recipe: RecipeModel
    onSave: (recipe: RecipeModel) => void
    onCancel: () => void
}

export function RecipeEditor({recipe, onSave, onCancel}: RecipeEditorProps) {
    /** draft of the new recipe */
    const [draft, setDraft] = useState<RecipeModel>(recipe)
    /** Error list */
    const [errors, setErrors] = useState<{ title?: boolean; ingredients?: boolean }>({})

    /**
     * Update ingredients
     * @param ingredientGroupList updated ingredient groups and ingredients
     */
    const updateIngredientGroupList = (ingredientGroupList: IngredientGroupModel[]) => {
        setDraft({...draft, ingredientGroupList})
    }

    /**
     * Update instruction steps
     * @param instructionStepList updated instructions
     */
    const updateInstructionList = (instructionStepList: InstructionStepModel[]) => {
        setDraft({...draft, instructionStepList})
    }

    /**
     * Validate recipe
     * @returns Information on the errors the validation encountered
     */
    const validate = () => {
        const newErrors: { title?: boolean; ingredients?: boolean } = {}

        // each recipe requires a title
        if (!draft.title.trim()) {
            newErrors.title = true
        }

        /* there must be at least one ingredient group
         * no group may contain an empty ingredient list
         * @todo check whether all ingredients are valid
         * @todo enhance visualization of ingredient errors
         */
        if (!draft.ingredientGroupList || draft.ingredientGroupList.length === 0) {
            newErrors.ingredients = true
        } else {
            const isAnyIngredientListEmpty = draft.ingredientGroupList.some(
                ingGrp => {
                    return !ingGrp.ingredientList || ingGrp.ingredientList.length === 0
                }
            )
            if (isAnyIngredientListEmpty) {
                newErrors.ingredients = true
            }
        }

        setErrors(newErrors)

        return Object.keys(newErrors).length === 0
    }
    /** Handles saving and ensures that the draft is only saved if valid */
    const handleSave = (draft: RecipeModel) => {
        if (validate()) {
            onSave(draft)
        }
    }
    // ensure that there is a recipe and show error otherwise
    if (!recipe) return <div>Oops, there's no recipe in RecipeEditor...</div>
    // @todo add handling of images
    return (
        /*Container spanning entire screen used to center content horizontally */
        <PageContainer>
            {/* Container defining the maximum width of the content */}
            <PageContentLayout>
                <h1 className="border-b-2 border-gray-300 pb-4">
                    {recipe.id ? "Rezept bearbeiten" : "Neues Rezept"}
                </h1>
                <ContentBody>
                    {/* Title */}
                    <h2>Titel</h2>
                    <input
                        className={`${errors.title ? "error-text" : ""}`}
                        placeholder="Titel"
                        value={draft.title}
                        onChange={e => setDraft({...draft, title: e.target.value})}
                    />
                    {/* Servings */}
                    <h2>Portionen</h2>
                    <div className="columns-3 gap-2 flex items-center">
                        <label>Für</label>
                        <input
                            type="number"
                            className="w-20"
                            placeholder="1"
                            value={draft.servings.amount}
                            onChange={e => {
                                const tempServings = draft.servings
                                tempServings.amount = Number(e.target.value)
                                setDraft({...draft, servings: tempServings})
                            }}
                        />
                        <input
                            placeholder="Personen"
                            value={draft.servings.unit}
                            onChange={e => {
                                const tempServings = draft.servings
                                tempServings.unit = e.target.value
                                setDraft({...draft, servings: tempServings})
                            }}
                        />
                    </div>
                    {/* Ingredient List - @todo better visualization of errors! */}
                    <div className={errors.ingredients ? "border error-text rounded p-2" : ""}>
                        <IngredientGroupListEditor
                            ingredientGroupList={draft.ingredientGroupList}
                            onChange={updateIngredientGroupList}
                        />
                    </div>

                    {/* Instruction List*/}
                    <InstructionStepListEditor
                        instructionStepList={draft.instructionStepList}
                        onChange={updateInstructionList}
                    />


                    <ButtonGroupLayout>
                        {/* Save Button */}
                        <Button
                            onClick={() => handleSave(draft)}
                            text={"Speichern"}
                            buttonType={ButtonType.PrimaryButton}
                        />
                        <Button
                            onClick={() => onCancel()}
                            text={"Abbrechen"}
                        />
                    </ButtonGroupLayout>
                </ContentBody>
            </PageContentLayout>
        </PageContainer>
    )
}
