"use client";

import { useState, useTransition, useRef } from "react";
import { useRouter } from "next/navigation";
import { createPlant, updatePlant } from "../server/actions";
import { SpeciesSearch } from "./species-search";
import type { PlantDetailDto, ContainerDto } from "../server/queries";
import type { SpeciesSuggestion } from "../server/species-lookup";

const CATEGORIES = [
  { value: "vegetable", label: "Vegetable" },
  { value: "fruit", label: "Fruit" },
  { value: "herb", label: "Herb" },
  { value: "flower", label: "Flower" },
  { value: "succulent", label: "Succulent" },
  { value: "cactus", label: "Cactus" },
  { value: "tropical", label: "Tropical" },
  { value: "tree", label: "Tree" },
  { value: "shrub", label: "Shrub" },
  { value: "other", label: "Other" },
];

const HEALTH_STATUSES = [
  { value: "healthy", label: "Healthy" },
  { value: "needs-attention", label: "Needs attention" },
  { value: "sick", label: "Sick" },
  { value: "dormant", label: "Dormant" },
];

const GROWTH_STAGES = [
  { value: "", label: "Unknown" },
  { value: "seedling", label: "Seedling" },
  { value: "sprout", label: "Sprout" },
  { value: "vegetative", label: "Vegetative" },
  { value: "budding", label: "Budding" },
  { value: "flowering", label: "Flowering" },
  { value: "ripening", label: "Ripening" },
  { value: "dormant", label: "Dormant" },
];

type Props = {
  existingPlant?: PlantDetailDto;
  defaultContainerId?: string | null;
  containers: ContainerDto[];
};

export function PlantForm({ existingPlant, defaultContainerId, containers }: Props) {
  const router = useRouter();
  const [error, setError] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();
  const [images, setImages] = useState<string[]>(existingPlant?.images ?? []);
  const [uploading, setUploading] = useState(false);
  const [selectedSpeciesId, setSelectedSpeciesId] = useState(existingPlant?.speciesId ?? "");

  const scientificNameRef = useRef<HTMLInputElement>(null);
  const sunlightRef = useRef<HTMLInputElement>(null);
  const wateringNotesRef = useRef<HTMLTextAreaElement>(null);

  function handleSpeciesSelect(species: SpeciesSuggestion) {
    setSelectedSpeciesId(species.id);
    if (scientificNameRef.current) scientificNameRef.current.value = species.scientific_name;
    if (sunlightRef.current) sunlightRef.current.value = species.sunlight.join(", ");
    if (wateringNotesRef.current) wateringNotesRef.current.value = species.watering;
  }

  async function handleImageSelect(e: React.ChangeEvent<HTMLInputElement>) {
    const files = Array.from(e.target.files ?? []);
    if (images.length >= 10) {
      setError("Maximum 10 images allowed.");
      return;
    }
    setUploading(true);
    setError(null);
    try {
      const urls: string[] = [];
      for (const file of files) {
        if (images.length + urls.length >= 10) break;
        const fd = new FormData();
        fd.append("file", file);
        const res = await fetch("/api/uploads", { method: "POST", body: fd });
        if (!res.ok) throw new Error("Upload failed");
        const data = (await res.json()) as { url: string };
        urls.push(data.url);
      }
      setImages((prev) => [...prev, ...urls]);
    } catch {
      setError("Image upload failed. Please try again.");
    } finally {
      setUploading(false);
      e.target.value = "";
    }
  }

  function handleRemoveImage(url: string) {
    setImages((prev) => prev.filter((u) => u !== url));
  }

  function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const fd = new FormData(e.currentTarget);

    const input = {
      name: fd.get("name") as string,
      category: (fd.get("category") as string) || "other",
      containerId: (fd.get("containerId") as string) || null,
      healthStatus: (fd.get("healthStatus") as string) || "healthy",
      growthStage: (fd.get("growthStage") as string) || null,
      scientificName: scientificNameRef.current?.value || null,
      speciesId: selectedSpeciesId || null,
      sunlight: sunlightRef.current?.value || null,
      wateringNotes: wateringNotesRef.current?.value || null,
      fertilizingNotes: (fd.get("fertilizingNotes") as string) || null,
      notes: (fd.get("notes") as string) || null,
      acquisitionDate: (fd.get("acquisitionDate") as string) || null,
      images,
      primaryImageUrl: existingPlant?.primaryImageUrl ?? images[0] ?? null,
    };

    setError(null);
    startTransition(async () => {
      try {
        if (existingPlant) {
          await updatePlant({ id: existingPlant.id, ...input });
          router.push(`/garden/plants/${existingPlant.id}`);
          router.refresh();
        } else {
          const plant = await createPlant(input);
          router.push(`/garden/plants/${plant.id}`);
        }
      } catch {
        setError("Something went wrong. Please try again.");
      }
    });
  }

  return (
    <form onSubmit={handleSubmit} className="flex flex-col gap-4 max-w-xl">
      <div className="flex flex-col gap-1">
        <label htmlFor="plant-name" className="text-sm font-medium">
          Name <span className="text-red-500">*</span>
        </label>
        <input
          id="plant-name"
          name="name"
          required
          maxLength={120}
          defaultValue={existingPlant?.name}
          className="input"
        />
      </div>

      <div className="flex flex-col gap-1">
        <label className="text-sm font-medium">Species lookup (optional)</label>
        <SpeciesSearch
          onSelect={handleSpeciesSelect}
          initialValue={existingPlant?.scientificName ?? ""}
        />
        <p className="text-xs text-[var(--ink-mute)]">
          Search OpenPlantBook to auto-fill scientific name and care notes.
        </p>
      </div>

      <div className="flex flex-col gap-1">
        <label htmlFor="plant-scientific-name" className="text-sm font-medium">
          Scientific name
        </label>
        <input
          id="plant-scientific-name"
          name="scientificName"
          ref={scientificNameRef}
          maxLength={200}
          defaultValue={existingPlant?.scientificName ?? ""}
          className="input"
        />
      </div>

      <div className="grid grid-cols-2 gap-3">
        <div className="flex flex-col gap-1">
          <label htmlFor="plant-category" className="text-sm font-medium">
            Category
          </label>
          <select
            id="plant-category"
            name="category"
            defaultValue={existingPlant?.category ?? "other"}
          >
            {CATEGORIES.map((c) => (
              <option key={c.value} value={c.value}>
                {c.label}
              </option>
            ))}
          </select>
        </div>
        <div className="flex flex-col gap-1">
          <label htmlFor="plant-container" className="text-sm font-medium">
            Container
          </label>
          <select
            id="plant-container"
            name="containerId"
            defaultValue={existingPlant?.containerId ?? defaultContainerId ?? ""}
          >
            <option value="">None</option>
            {containers.map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
              </option>
            ))}
          </select>
        </div>
      </div>

      <div className="grid grid-cols-2 gap-3">
        <div className="flex flex-col gap-1">
          <label htmlFor="plant-health" className="text-sm font-medium">
            Health status
          </label>
          <select
            id="plant-health"
            name="healthStatus"
            defaultValue={existingPlant?.healthStatus ?? "healthy"}
          >
            {HEALTH_STATUSES.map((h) => (
              <option key={h.value} value={h.value}>
                {h.label}
              </option>
            ))}
          </select>
        </div>
        <div className="flex flex-col gap-1">
          <label htmlFor="plant-stage" className="text-sm font-medium">
            Growth stage
          </label>
          <select
            id="plant-stage"
            name="growthStage"
            defaultValue={existingPlant?.growthStage ?? ""}
          >
            {GROWTH_STAGES.map((g) => (
              <option key={g.value} value={g.value}>
                {g.label}
              </option>
            ))}
          </select>
        </div>
      </div>

      <div className="flex flex-col gap-1">
        <label htmlFor="plant-acquired" className="text-sm font-medium">
          Acquisition date
        </label>
        <input
          id="plant-acquired"
          type="date"
          name="acquisitionDate"
          defaultValue={existingPlant?.acquisitionDate ?? ""}
          className="input"
        />
      </div>

      <div className="flex flex-col gap-1">
        <label htmlFor="plant-sunlight" className="text-sm font-medium">
          Sunlight requirements
        </label>
        <input
          id="plant-sunlight"
          name="sunlight"
          ref={sunlightRef}
          maxLength={200}
          defaultValue={existingPlant?.sunlight ?? ""}
          placeholder="e.g. full sun, part shade"
          className="input"
        />
      </div>

      <div className="flex flex-col gap-1">
        <label htmlFor="plant-watering" className="text-sm font-medium">
          Watering notes
        </label>
        <textarea
          id="plant-watering"
          name="wateringNotes"
          ref={wateringNotesRef}
          maxLength={2000}
          rows={2}
          defaultValue={existingPlant?.wateringNotes ?? ""}
          className="input"
        />
      </div>

      <div className="flex flex-col gap-1">
        <label htmlFor="plant-fertilizing" className="text-sm font-medium">
          Fertilizing notes
        </label>
        <textarea
          id="plant-fertilizing"
          name="fertilizingNotes"
          maxLength={2000}
          rows={2}
          defaultValue={existingPlant?.fertilizingNotes ?? ""}
          className="input"
        />
      </div>

      <div className="flex flex-col gap-1">
        <label htmlFor="plant-notes" className="text-sm font-medium">
          General notes
        </label>
        <textarea
          id="plant-notes"
          name="notes"
          maxLength={2000}
          rows={3}
          defaultValue={existingPlant?.notes ?? ""}
          className="input"
        />
      </div>

      <div className="flex flex-col gap-2">
        <label className="text-sm font-medium">Photos ({images.length}/10)</label>
        {images.length > 0 && (
          <div className="grid grid-cols-4 gap-2">
            {images.map((url) => (
              <div key={url} className="relative group">
                <img src={url} alt="" className="w-full aspect-square object-cover rounded" />
                <button
                  type="button"
                  onClick={() => handleRemoveImage(url)}
                  className="absolute top-0.5 right-0.5 bg-black/60 text-white rounded text-xs px-1 opacity-0 group-hover:opacity-100"
                >
                  ✕
                </button>
              </div>
            ))}
          </div>
        )}
        {images.length < 10 && (
          <label className="btn btn-ghost btn-sm w-fit cursor-pointer">
            {uploading ? "Uploading…" : "Add photos"}
            <input
              type="file"
              accept="image/*"
              multiple
              className="hidden"
              onChange={handleImageSelect}
              disabled={uploading}
            />
          </label>
        )}
      </div>

      {error && <p className="text-sm text-red-500">{error}</p>}

      <div className="flex gap-2 justify-end">
        <a
          href={existingPlant ? `/garden/plants/${existingPlant.id}` : "/garden"}
          className="btn btn-ghost"
        >
          Cancel
        </a>
        <button type="submit" className="btn btn-primary" disabled={isPending || uploading}>
          {isPending ? "Saving…" : existingPlant ? "Save" : "Create"}
        </button>
      </div>
    </form>
  );
}
