import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import {
  createRecipe,
  deleteRecipeImage,
  getRecipe,
  updateRecipe,
  uploadRecipeImage,
  uploadedImageUrl,
} from "../api/client";
import IngredientRow from "../components/IngredientRow";
import NutritionFields from "../components/NutritionFields";
import StepRow from "../components/StepRow";
import TimingFields from "../components/TimingFields";
import type { Ingredient, RecipeInput, Step } from "../types/recipe";

const EMPTY_RECIPE: RecipeInput = {
  name: "",
  category: "",
  preptime: "",
  cooktime: "",
  baketime: "",
  cooltime: "",
  marinade_time: "",
  robot_time: "",
  servings: "",
  notes: "",
  kcal: "",
  kh: "",
  protein: "",
  fett: "",
  ingredients: [],
  steps: [],
};

function reorder<T>(items: T[], index: number, direction: -1 | 1): T[] {
  const target = index + direction;
  if (target < 0 || target >= items.length) return items;
  const copy = [...items];
  [copy[index], copy[target]] = [copy[target], copy[index]];
  return copy;
}

export default function RecipeFormPage() {
  const { id } = useParams();
  const isEdit = Boolean(id);
  const navigate = useNavigate();

  const [form, setForm] = useState<RecipeInput>(EMPTY_RECIPE);
  const [existingImage, setExistingImage] = useState<string | null>(null);
  const [imageFile, setImageFile] = useState<File | null>(null);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!id) return;
    getRecipe(Number(id)).then((recipe) => {
      setForm({
        name: recipe.name,
        category: recipe.category ?? "",
        preptime: recipe.preptime ?? "",
        cooktime: recipe.cooktime ?? "",
        baketime: recipe.baketime ?? "",
        cooltime: recipe.cooltime ?? "",
        marinade_time: recipe.marinade_time ?? "",
        robot_time: recipe.robot_time ?? "",
        servings: recipe.servings ?? "",
        notes: recipe.notes ?? "",
        kcal: recipe.kcal ?? "",
        kh: recipe.kh ?? "",
        protein: recipe.protein ?? "",
        fett: recipe.fett ?? "",
        ingredients: recipe.ingredients,
        steps: recipe.steps,
      });
      setExistingImage(recipe.image_filename ?? null);
    });
  }, [id]);

  function updateField<K extends keyof RecipeInput>(field: K, value: RecipeInput[K]) {
    setForm((prev) => ({ ...prev, [field]: value }));
  }

  function updateIngredient(index: number, ingredient: Ingredient) {
    setForm((prev) => ({
      ...prev,
      ingredients: prev.ingredients.map((it, i) => (i === index ? ingredient : it)),
    }));
  }

  function addIngredient() {
    setForm((prev) => ({
      ...prev,
      ingredients: [...prev.ingredients, { kind: "item", quantity: "", unit: "", text: "" }],
    }));
  }

  function removeIngredient(index: number) {
    setForm((prev) => ({ ...prev, ingredients: prev.ingredients.filter((_, i) => i !== index) }));
  }

  function moveIngredient(index: number, direction: -1 | 1) {
    setForm((prev) => ({ ...prev, ingredients: reorder(prev.ingredients, index, direction) }));
  }

  function updateStep(index: number, step: Step) {
    setForm((prev) => ({ ...prev, steps: prev.steps.map((it, i) => (i === index ? step : it)) }));
  }

  function addStep() {
    setForm((prev) => ({ ...prev, steps: [...prev.steps, { text: "" }] }));
  }

  function removeStep(index: number) {
    setForm((prev) => ({ ...prev, steps: prev.steps.filter((_, i) => i !== index) }));
  }

  function moveStep(index: number, direction: -1 | 1) {
    setForm((prev) => ({ ...prev, steps: reorder(prev.steps, index, direction) }));
  }

  async function handleRemoveExistingImage() {
    if (!id) return;
    await deleteRecipeImage(Number(id));
    setExistingImage(null);
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!form.name.trim()) {
      setError("Bitte einen Namen angeben.");
      return;
    }
    setSaving(true);
    setError(null);
    try {
      const recipe = isEdit ? await updateRecipe(Number(id), form) : await createRecipe(form);
      if (imageFile) {
        await uploadRecipeImage(recipe.id, imageFile);
      }
      navigate(`/recipes/${recipe.id}`);
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setSaving(false);
    }
  }

  return (
    <form className="page" onSubmit={handleSubmit}>
      <div className="page-header">
        <h1>{isEdit ? "Rezept bearbeiten" : "Neues Rezept"}</h1>
        <div className="actions">
          <button type="submit" className="button primary" disabled={saving}>
            {saving ? "Speichern…" : "Speichern"}
          </button>
        </div>
      </div>

      {error && <p className="error">{error}</p>}

      <div className="field-grid">
        <label>
          Name
          <input value={form.name} onChange={(e) => updateField("name", e.target.value)} required />
        </label>
        <label>
          Kategorie
          <input
            value={form.category ?? ""}
            placeholder="z.B. Hauptspeisen, Beilagen, Nachspeisen"
            onChange={(e) => updateField("category", e.target.value)}
          />
        </label>
      </div>

      <h2>Bild</h2>
      {existingImage && !imageFile && (
        <div className="image-preview">
          <img src={uploadedImageUrl(existingImage)} alt="" />
          <button type="button" onClick={handleRemoveExistingImage}>Bild entfernen</button>
        </div>
      )}
      {imageFile && (
        <div className="image-preview">
          <img src={URL.createObjectURL(imageFile)} alt="" />
          <button type="button" onClick={() => setImageFile(null)}>Auswahl verwerfen</button>
        </div>
      )}
      <input
        type="file"
        accept="image/png,image/jpeg,image/webp"
        onChange={(e) => setImageFile(e.target.files?.[0] ?? null)}
      />

      <h2>Zeiten & Portionen</h2>
      <TimingFields value={form} onChange={updateField} />

      <h2>Zutaten</h2>
      <div className="row-list">
        {form.ingredients.map((ingredient, index) => (
          <IngredientRow
            key={index}
            ingredient={ingredient}
            onChange={(value) => updateIngredient(index, value)}
            onRemove={() => removeIngredient(index)}
            onMoveUp={() => moveIngredient(index, -1)}
            onMoveDown={() => moveIngredient(index, 1)}
          />
        ))}
      </div>
      <button type="button" className="button" onClick={addIngredient}>+ Zutat</button>

      <h2>Notizen</h2>
      <textarea
        value={form.notes ?? ""}
        onChange={(e) => updateField("notes", e.target.value)}
        rows={3}
      />

      <h2>Zubereitung</h2>
      <div className="row-list">
        {form.steps.map((step, index) => (
          <StepRow
            key={index}
            step={step}
            index={index}
            onChange={(value) => updateStep(index, value)}
            onRemove={() => removeStep(index)}
            onMoveUp={() => moveStep(index, -1)}
            onMoveDown={() => moveStep(index, 1)}
          />
        ))}
      </div>
      <button type="button" className="button" onClick={addStep}>+ Schritt</button>

      <h2>Nährwerte (pro Portion)</h2>
      <NutritionFields value={form} onChange={updateField} />
    </form>
  );
}
