import { useState } from "react"
import type { Recipe } from "../../types/recipe"
import type { IngredientGroup } from "../../types/ingredientGroup"
import { IngredientGroupListEditor } from "./IngredientGroupListEditor"

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

/**
 * Editor component for managing a recipe, including title,
 * ingredients (with amount, unit, name), instructions, and image URL.
 * @todo adapt to ingredientGroups!
 */
export default function RecipeEditor({ recipe, onSave, onCancel }: RecipeEditorProps) {
  /** draft of the new recipe */
  const [draft, setDraft] = useState<Recipe>(recipe)
  /** Error list */
  const [errors, setErrors] = useState<{ title?: boolean; ingredients?: boolean }>({})

  /**
   * Update ingredients
   * @param ingredients new ingredients
   */
  const updateIngredientGroupList = (ingredientGroupList: IngredientGroup[]) => {
    setDraft({ ...draft, ingredientGroupList })
  }
  /**
   * 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 {
      let 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: Recipe) => {
    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 (
    <div className="p-4 gap-10">
      <h2 className="content-title">
        {recipe.id ? "Edit Recipe" : "New Recipe"}
      </h2>

      {/* Title */}
      <h3 className="subsection-heading">Title</h3>
      <input
        className={`input-field ${errors.title ? "border-red-500" : ""}`}
        placeholder="Title"
        value={draft.title}
        onChange={e => setDraft({ ...draft, title: e.target.value })}
      />
      {/* Servings */}
      <h3 className="subsection-heading">Servings</h3>
      <div className="columns-3 gap-2 flex items-center">
        <label>For</label>
        <input
          type="number"
          className="input-field 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
          className="input-field"
          placeholder="Persons"
          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 border-red-500 rounded p-2" : ""}>
      <IngredientGroupListEditor
        ingredientGroupList={draft.ingredientGroupList}
        onChange={updateIngredientGroupList}
      />
      </div>

      <h3 className="subsection-heading">Instructions</h3>
      {/* Instructions */}
      <textarea
        className="input-field"
        placeholder="Instructions"
        value={draft.instructions}
        onChange={e => setDraft({ ...draft, instructions: e.target.value })}
      />

      <div className="button-group">
        {/* Save Button */}
        <button
          className="primary-button"
          onClick={() => handleSave(draft)}
        >
          Save
        </button>
        <button
          className="default-button"
          onClick={() => onCancel()}
        >
          Cancel
        </button>
      </div>
    </div>
    )
}
