"use client";

import { useState, useRef, KeyboardEvent } from "react";
import { useRouter } from "next/navigation";
import { Plus, Trash2, GripVertical, X, Tag } from "lucide-react";
import { toast } from "sonner";
import { useTranslations } from "next-intl";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { DietaryTagPicker } from "./dietary-tag-picker";
import { PhotoUploader, type PhotoEntry } from "./photo-uploader";

type DietaryTags = {
  vegan?: boolean;
  vegetarian?: boolean;
  glutenFree?: boolean;
  dairyFree?: boolean;
  nutFree?: boolean;
  halal?: boolean;
  kosher?: boolean;
};

type IngredientRow = {
  id: string;
  rawName: string;
  quantity: string;
  unit: string;
  note: string;
};

type StepRow = {
  id: string;
  instruction: string;
  timerSeconds: string;
};

type RecipeFormProps = {
  recipeId?: string;
  defaultValues?: {
    title?: string;
    description?: string;
    baseServings?: number;
    visibility?: "private" | "unlisted" | "public";
    difficulty?: "easy" | "medium" | "hard" | null;
    prepMins?: number | null;
    cookMins?: number | null;
    dietaryTags?: DietaryTags;
    tags?: string[];
    ingredients?: IngredientRow[];
    steps?: StepRow[];
    photos?: PhotoEntry[];
  };
};

function newIngredient(): IngredientRow {
  return { id: crypto.randomUUID(), rawName: "", quantity: "", unit: "", note: "" };
}

function newStep(): StepRow {
  return { id: crypto.randomUUID(), instruction: "", timerSeconds: "" };
}

export function RecipeForm({ recipeId, defaultValues }: RecipeFormProps) {
  const router = useRouter();
  const t = useTranslations("recipeForm");
  const t_recipe = useTranslations("recipe");
  const t_common = useTranslations("common");
  const isEdit = !!recipeId;
  const id = recipeId ?? crypto.randomUUID();

  const [title, setTitle] = useState(defaultValues?.title ?? "");
  const [description, setDescription] = useState(defaultValues?.description ?? "");
  const [baseServings, setBaseServings] = useState(String(defaultValues?.baseServings ?? 4));
  const [visibility, setVisibility] = useState<"private" | "unlisted" | "public">(defaultValues?.visibility ?? "private");
  const [difficulty, setDifficulty] = useState<"easy" | "medium" | "hard" | "">(defaultValues?.difficulty ?? "");
  const [prepMins, setPrepMins] = useState(String(defaultValues?.prepMins ?? ""));
  const [cookMins, setCookMins] = useState(String(defaultValues?.cookMins ?? ""));
  const [tags, setTags] = useState<string[]>(defaultValues?.tags ?? []);
  const [tagInput, setTagInput] = useState("");
  const tagInputRef = useRef<HTMLInputElement>(null);
  const [dietaryTags, setDietaryTags] = useState<DietaryTags>(defaultValues?.dietaryTags ?? {});
  const [ingredients, setIngredients] = useState<IngredientRow[]>(
    defaultValues?.ingredients?.length ? defaultValues.ingredients : [newIngredient()]
  );
  const [steps, setSteps] = useState<StepRow[]>(
    defaultValues?.steps?.length ? defaultValues.steps : [newStep()]
  );
  const [photos, setPhotos] = useState<PhotoEntry[]>(defaultValues?.photos ?? []);
  const [saving, setSaving] = useState(false);

  function updateIngredient(i: number, patch: Partial<IngredientRow>) {
    setIngredients((prev) => prev.map((row, idx) => idx === i ? { ...row, ...patch } : row));
  }

  function removeIngredient(i: number) {
    setIngredients((prev) => prev.filter((_, idx) => idx !== i));
  }

  function addTag(raw: string) {
    const tag = raw.trim().toLowerCase().slice(0, 50);
    if (!tag || tags.includes(tag) || tags.length >= 20) return;
    setTags((prev) => [...prev, tag]);
    setTagInput("");
  }

  function removeTag(tag: string) {
    setTags((prev) => prev.filter((t) => t !== tag));
  }

  function handleTagKeyDown(e: KeyboardEvent<HTMLInputElement>) {
    if (e.key === "Enter") {
      e.preventDefault();
      addTag(tagInput);
    } else if (e.key === "Backspace" && !tagInput && tags.length > 0) {
      setTags((prev) => prev.slice(0, -1));
    }
  }

  function updateStep(i: number, patch: Partial<StepRow>) {
    setSteps((prev) => prev.map((row, idx) => idx === i ? { ...row, ...patch } : row));
  }

  function removeStep(i: number) {
    setSteps((prev) => prev.filter((_, idx) => idx !== i));
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!title.trim()) {
      toast.error(t("titleRequired"));
      return;
    }

    setSaving(true);
    try {
      const payload = {
        title: title.trim(),
        description: description.trim() || undefined,
        baseServings: parseInt(baseServings) || 4,
        visibility,
        difficulty: difficulty || undefined,
        prepMins: prepMins ? parseInt(prepMins) : undefined,
        cookMins: cookMins ? parseInt(cookMins) : undefined,
        tags,
        dietaryTags,
        ingredients: ingredients
          .filter((ing) => ing.rawName.trim())
          .map((ing, i) => ({
            rawName: ing.rawName.trim(),
            quantity: ing.quantity.trim() || undefined,
            unit: ing.unit.trim() || undefined,
            note: ing.note.trim() || undefined,
            order: i,
          })),
        steps: steps
          .filter((s) => s.instruction.trim())
          .map((s, i) => ({
            instruction: s.instruction.trim(),
            timerSeconds: s.timerSeconds ? parseInt(s.timerSeconds) : undefined,
            order: i,
          })),
      };

      const url = isEdit ? `/api/v1/recipes/${id}` : "/api/v1/recipes";
      const method = isEdit ? "PUT" : "POST";

      const res = await fetch(url, {
        method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });

      if (!res.ok) {
        const err = await res.json() as { error?: string };
        toast.error(err.error ?? t("saveError"));
        return;
      }

      const saved = await res.json() as { id: string };
      toast.success(isEdit ? t("updateSuccess") : t("createSuccess"));
      router.push(`/recipes/${saved.id}`);
      router.refresh();
    } finally {
      setSaving(false);
    }
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-8 max-w-3xl">
      {/* Basic info */}
      <div className="space-y-4">
        <div className="space-y-2">
          <Label htmlFor="title">{t("titleLabel")}</Label>
          <Input
            id="title"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder={t("titlePlaceholder")}
            required
          />
        </div>

        <div className="space-y-2">
          <Label htmlFor="description">{t("descriptionLabel")}</Label>
          <Textarea
            id="description"
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            placeholder={t("descriptionPlaceholder")}
            rows={3}
          />
        </div>

        <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
          <div className="space-y-2">
            <Label htmlFor="servings">{t("servings")}</Label>
            <Input
              id="servings"
              type="number"
              min={1}
              max={100}
              value={baseServings}
              onChange={(e) => setBaseServings(e.target.value)}
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="prep">{t("prepMins")}</Label>
            <Input
              id="prep"
              type="number"
              min={0}
              value={prepMins}
              onChange={(e) => setPrepMins(e.target.value)}
              placeholder="0"
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="cook">{t("cookMins")}</Label>
            <Input
              id="cook"
              type="number"
              min={0}
              value={cookMins}
              onChange={(e) => setCookMins(e.target.value)}
              placeholder="0"
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="difficulty">{t("difficulty")}</Label>
            <select
              id="difficulty"
              value={difficulty}
              onChange={(e) => setDifficulty(e.target.value as "easy" | "medium" | "hard" | "")}
              className="flex h-8 w-full rounded-lg border border-input bg-transparent px-2.5 py-1 text-sm outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50"
            >
              <option value="">—</option>
              <option value="easy">{t_recipe("difficulty.easy")}</option>
              <option value="medium">{t_recipe("difficulty.medium")}</option>
              <option value="hard">{t_recipe("difficulty.hard")}</option>
            </select>
          </div>
        </div>

        <div className="space-y-2">
          <Label htmlFor="visibility">{t("visibility")}</Label>
          <select
            id="visibility"
            value={visibility}
            onChange={(e) => setVisibility(e.target.value as "private" | "unlisted" | "public")}
            className="flex h-8 w-full max-w-[200px] rounded-lg border border-input bg-transparent px-2.5 py-1 text-sm outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50"
          >
            <option value="private">{t_recipe("visibility.private")}</option>
            <option value="unlisted">{t_recipe("visibility.unlisted")}</option>
            <option value="public">{t_recipe("visibility.public")}</option>
          </select>
        </div>

        {/* Tags */}
        <div className="space-y-2">
          <Label>Tags</Label>
          <div
            className="flex flex-wrap gap-1.5 min-h-[36px] rounded-lg border border-input bg-transparent px-2.5 py-1.5 cursor-text focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50"
            onClick={() => tagInputRef.current?.focus()}
          >
            {tags.map((tag) => (
              <span
                key={tag}
                className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md text-xs bg-muted text-muted-foreground"
              >
                <Tag className="h-2.5 w-2.5" />
                {tag}
                <button
                  type="button"
                  onClick={(e) => { e.stopPropagation(); removeTag(tag); }}
                  className="hover:text-foreground transition-colors"
                  aria-label={`Remove tag ${tag}`}
                >
                  <X className="h-2.5 w-2.5" />
                </button>
              </span>
            ))}
            {tags.length < 20 && (
              <input
                ref={tagInputRef}
                value={tagInput}
                onChange={(e) => setTagInput(e.target.value)}
                onKeyDown={handleTagKeyDown}
                onBlur={() => { if (tagInput.trim()) addTag(tagInput); }}
                placeholder={tags.length === 0 ? "Add tags… (press Enter)" : ""}
                className="flex-1 min-w-[120px] bg-transparent text-sm outline-none placeholder:text-muted-foreground"
              />
            )}
          </div>
          <p className="text-xs text-muted-foreground">Press Enter to add · Backspace to remove last · max 20 tags</p>
        </div>
      </div>

      <Separator />

      {/* Dietary tags */}
      <div className="space-y-2">
        <Label>{t("dietaryTags")}</Label>
        <DietaryTagPicker value={dietaryTags} onChange={setDietaryTags} />
      </div>

      <Separator />

      {/* Photos */}
      <div className="space-y-2">
        <Label>{t("photos")}</Label>
        <PhotoUploader recipeId={id} photos={photos} onChange={setPhotos} />
      </div>

      <Separator />

      {/* Ingredients */}
      <div className="space-y-3">
        <Label>{t("ingredients")}</Label>
        <div className="space-y-2">
          {ingredients.map((ing, i) => (
            <div key={ing.id} className="flex gap-2 items-start">
              <GripVertical className="h-4 w-4 text-muted-foreground mt-2 cursor-grab shrink-0" />
              <Input
                value={ing.quantity}
                onChange={(e) => updateIngredient(i, { quantity: e.target.value })}
                placeholder={t("amount")}
                className="w-16 shrink-0"
              />
              <Input
                value={ing.unit}
                onChange={(e) => updateIngredient(i, { unit: e.target.value })}
                placeholder={t("unit")}
                className="w-24 shrink-0"
              />
              <Input
                value={ing.rawName}
                onChange={(e) => updateIngredient(i, { rawName: e.target.value })}
                placeholder={t("ingredient")}
                className="flex-1 min-w-0"
              />
              <Input
                value={ing.note}
                onChange={(e) => updateIngredient(i, { note: e.target.value })}
                placeholder={t("note")}
                className="w-48 shrink-0"
              />
              <button
                type="button"
                onClick={() => removeIngredient(i)}
                disabled={ingredients.length === 1}
                className="mt-1.5 text-muted-foreground hover:text-destructive transition-colors disabled:opacity-30"
              >
                <Trash2 className="h-4 w-4" />
              </button>
            </div>
          ))}
        </div>
        <Button
          type="button"
          variant="outline"
          size="sm"
          onClick={() => setIngredients((p) => [...p, newIngredient()])}
        >
          <Plus className="h-4 w-4" />
          {t("addIngredient")}
        </Button>
      </div>

      <Separator />

      {/* Steps */}
      <div className="space-y-3">
        <Label>{t("steps")}</Label>
        <div className="space-y-3">
          {steps.map((step, i) => (
            <div key={step.id} className="flex gap-3 items-start">
              <div className="mt-2.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-bold text-muted-foreground">
                {i + 1}
              </div>
              <Textarea
                value={step.instruction}
                onChange={(e) => updateStep(i, { instruction: e.target.value })}
                placeholder={t("stepPlaceholder", { n: i + 1 })}
                rows={2}
                className="flex-1 min-w-0"
              />
              <Input
                value={step.timerSeconds}
                onChange={(e) => updateStep(i, { timerSeconds: e.target.value })}
                placeholder={t("timerSeconds")}
                type="number"
                min={0}
                className="w-28 shrink-0"
              />
              <button
                type="button"
                onClick={() => removeStep(i)}
                disabled={steps.length === 1}
                className="mt-2.5 text-muted-foreground hover:text-destructive transition-colors disabled:opacity-30"
              >
                <Trash2 className="h-4 w-4" />
              </button>
            </div>
          ))}
        </div>
        <Button
          type="button"
          variant="outline"
          size="sm"
          onClick={() => setSteps((p) => [...p, newStep()])}
        >
          <Plus className="h-4 w-4" />
          {t("addStep")}
        </Button>
      </div>

      <Separator />

      <div className="flex gap-3">
        <Button type="submit" disabled={saving}>
          {saving ? t("saving") : isEdit ? t("saveChanges") : t("createRecipe")}
        </Button>
        <Button type="button" variant="outline" onClick={() => router.back()}>
          {t_common("cancel")}
        </Button>
      </div>
    </form>
  );
}
