"use client";

import { useRef, useState } from "react";
import { useRouter } from "next/navigation";
import Image from "next/image";
import { useFamily } from "@/app/FamilyProvider";
import { Button } from "@/components/ui";
import { GARMENT_CATEGORIES, GARMENT_SIZE_ORDER } from "@/db/schema/wardrobe";

type Step = "capture" | "tagging" | "form";

interface VisionResult {
  name: string;
  category: string;
  colors: string[];
  seasons: string[];
  occasion_tags: string[];
}

const SEASON_OPTIONS = ["summer", "monsoon", "winter"];
const OCCASION_OPTIONS = ["everyday", "daycare", "festive", "photoshoot"];
const ACQUIRED_OPTIONS = ["bought", "gift", "handmedown"];

const CATEGORY_LABELS: Record<string, string> = {
  onesie: "Onesie", top: "Top", bottom: "Bottom", dress: "Dress",
  outerwear: "Jacket", sleepwear: "Sleepwear", accessory: "Accessory",
};

const CATEGORY_COLORS: Record<string, string> = {
  onesie: "bg-pink-100 text-pink-700", top: "bg-blue-100 text-blue-700",
  bottom: "bg-indigo-100 text-indigo-700", dress: "bg-purple-100 text-purple-700",
  outerwear: "bg-teal-100 text-teal-700", sleepwear: "bg-amber-100 text-amber-700",
  accessory: "bg-rose-100 text-rose-700",
};

function ChipRow<T extends string>({
  label, options, selected, onChange, required, optionLabel,
}: {
  label: string;
  options: readonly T[];
  selected: T[];
  onChange: (v: T[]) => void;
  required?: boolean;
  optionLabel?: (v: T) => string;
}) {
  const toggle = (v: T) => {
    if (selected.includes(v)) onChange(selected.filter(x => x !== v));
    else onChange([...selected, v]);
  };
  return (
    <div className="mb-4">
      <p className="text-sm font-semibold text-gray-600 dark:text-gray-300 mb-2">
        {label}{required && <span className="text-red-500 ml-0.5">*</span>}
      </p>
      <div className="flex flex-wrap gap-2">
        {options.map(o => (
          <button
            key={o}
            type="button"
            onClick={() => toggle(o)}
            className={`px-3 py-1.5 rounded-full text-sm font-medium transition-all ${
              selected.includes(o)
                ? "bg-rose-400 text-white shadow-sm scale-105"
                : "bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300"
            }`}
          >
            {optionLabel ? optionLabel(o) : o}
          </button>
        ))}
      </div>
    </div>
  );
}

function SingleChipRow<T extends string>({
  label, options, selected, onChange, required, optionLabel,
}: {
  label: string;
  options: readonly T[];
  selected: T | null;
  onChange: (v: T) => void;
  required?: boolean;
  optionLabel?: (v: T) => string;
}) {
  return (
    <div className="mb-4">
      <p className="text-sm font-semibold text-gray-600 dark:text-gray-300 mb-2">
        {label}{required && <span className="text-red-500 ml-0.5">*</span>}
      </p>
      <div className="flex flex-wrap gap-2">
        {options.map(o => (
          <button
            key={o}
            type="button"
            onClick={() => onChange(o)}
            className={`px-3 py-1.5 rounded-full text-sm font-medium transition-all ${
              selected === o
                ? "bg-rose-400 text-white shadow-sm scale-105"
                : "bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300"
            }`}
          >
            {optionLabel ? optionLabel(o) : o}
          </button>
        ))}
      </div>
    </div>
  );
}

export default function AddGarmentPage() {
  const { childId } = useFamily();
  const router = useRouter();
  const fileRef = useRef<HTMLInputElement>(null);

  const [step, setStep] = useState<Step>("capture");
  const [preview, setPreview] = useState<string | null>(null);
  const [thumbUrl, setThumbUrl] = useState<string | null>(null);
  const [imageKey, setImageKey] = useState("");
  const [thumbKey, setThumbKey] = useState("");
  const [error, setError] = useState("");
  const [saving, setSaving] = useState(false);

  // Form fields
  const [name, setName] = useState("");
  const [category, setCategory] = useState<string | null>(null);
  const [sizeLabel, setSizeLabel] = useState<string | null>(null);
  const [colors, setColors] = useState<string[]>([]);
  const [colorInput, setColorInput] = useState("");
  const [seasons, setSeasons] = useState<string[]>([]);
  const [occasionTags, setOccasionTags] = useState<string[]>([]);
  const [acquiredVia, setAcquiredVia] = useState<string | null>(null);
  const [giftFrom, setGiftFrom] = useState("");
  const [visionMetadata, setVisionMetadata] = useState<VisionResult | null>(null);

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setError("");
    setStep("tagging");

    // Show local preview immediately
    const reader = new FileReader();
    reader.onload = ev => setPreview(ev.target?.result as string);
    reader.readAsDataURL(file);

    // Upload to R2
    const form = new FormData();
    form.append("file", file);
    let uploadRes;
    try {
      uploadRes = await fetch("/api/garments/upload", { method: "POST", body: form });
      if (!uploadRes.ok) throw new Error((await uploadRes.json()).error);
    } catch (err) {
      setError(`Upload failed: ${err}`);
      setStep("capture");
      return;
    }
    const { imageKey: ik, thumbKey: tk, thumbUrl: tu } = await uploadRes.json();
    setImageKey(ik);
    setThumbKey(tk);
    setThumbUrl(tu);

    // Vision tagging
    let vision: VisionResult = { name: "", category: "top", colors: [], seasons: [], occasion_tags: [] };
    try {
      const tagRes = await fetch("/api/garments/tag", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ imageKey: ik }),
      });
      if (tagRes.ok) {
        const tagData = await tagRes.json();
        vision = tagData;
      }
    } catch {
      // Vision failure is non-fatal — proceed with empty defaults
    }

    setVisionMetadata(vision);
    setName(vision.name || "");
    setCategory(vision.category || null);
    setColors(vision.colors || []);
    setSeasons(vision.seasons || []);
    setOccasionTags(vision.occasion_tags || []);
    setStep("form");
  };

  const addColor = () => {
    const c = colorInput.trim().toLowerCase();
    if (c && !colors.includes(c)) setColors([...colors, c]);
    setColorInput("");
  };

  const handleSave = async () => {
    if (!childId || !category || !sizeLabel) return;
    setSaving(true);
    setError("");
    try {
      const res = await fetch("/api/garments", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          childId,
          name: name || null,
          category,
          sizeLabel,
          colors,
          seasons,
          occasionTags,
          imageKey,
          thumbKey,
          acquiredVia: acquiredVia || null,
          giftFrom: giftFrom || null,
          visionMetadata,
        }),
      });
      if (!res.ok) throw new Error((await res.json()).error);
      handleAddAnother();
    } catch (err) {
      setError(`Save failed: ${err}`);
    } finally {
      setSaving(false);
    }
  };

  const handleAddAnother = () => {
    setStep("capture");
    setPreview(null);
    setThumbUrl(null);
    setImageKey("");
    setThumbKey("");
    setName("");
    setCategory(null);
    setSizeLabel(null);
    setColors([]);
    setColorInput("");
    setSeasons([]);
    setOccasionTags([]);
    setAcquiredVia(null);
    setGiftFrom("");
    setVisionMetadata(null);
    setError("");
    if (fileRef.current) fileRef.current.value = "";
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-pink-50 via-purple-50 to-amber-50 dark:from-gray-900 dark:to-gray-800 pb-24">
      {/* Header */}
      <div className="flex items-center gap-3 p-4">
        <button onClick={() => router.back()} className="p-2 rounded-xl bg-white dark:bg-gray-800 shadow-sm text-xl">←</button>
        <h1 className="text-xl font-bold">Add Garment</h1>
        {step === "form" && (
          <span className="ml-auto text-xs text-gray-400 bg-white dark:bg-gray-800 px-2 py-1 rounded-full shadow-sm">
            ✨ Vision pre-filled
          </span>
        )}
      </div>

      {error && (
        <div className="mx-4 mb-3 p-3 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-700 rounded-xl text-sm text-red-700 dark:text-red-300">
          {error}
        </div>
      )}

      {/* Step 1: Capture */}
      {step === "capture" && (
        <div className="mx-4 mt-4">
          <div
            onClick={() => fileRef.current?.click()}
            className="aspect-square rounded-3xl border-4 border-dashed border-rose-200 dark:border-gray-600 flex flex-col items-center justify-center gap-4 cursor-pointer hover:border-rose-400 transition-colors bg-white dark:bg-gray-800"
          >
            <span className="text-6xl">👚</span>
            <div className="text-center px-4">
              <p className="font-semibold text-gray-700 dark:text-gray-200">Take or upload a photo</p>
              <p className="text-sm text-gray-400 mt-1">Tip: flat-lay on a light surface for best tagging</p>
            </div>
            <span className="px-4 py-2 bg-rose-400 text-white rounded-full text-sm font-medium">
              📷 Add Photo
            </span>
          </div>
          <input
            ref={fileRef}
            type="file"
            accept="image/*"
            capture="environment"
            className="hidden"
            onChange={handleFileChange}
          />
        </div>
      )}

      {/* Step 2: Tagging spinner */}
      {step === "tagging" && (
        <div className="mx-4 mt-4 flex flex-col items-center gap-6">
          {preview && (
            <div className="w-48 h-48 rounded-2xl overflow-hidden shadow-lg">
              <img src={preview} alt="preview" className="w-full h-full object-cover" />
            </div>
          )}
          <div className="text-center">
            <div className="flex gap-1 justify-center mb-3">
              {[0, 150, 300].map(d => (
                <span key={d} className="w-2.5 h-2.5 bg-rose-400 rounded-full animate-bounce" style={{ animationDelay: `${d}ms` }} />
              ))}
            </div>
            <p className="font-semibold text-gray-700 dark:text-gray-200">Analysing garment…</p>
            <p className="text-sm text-gray-400">Vision is detecting category & colors</p>
          </div>
        </div>
      )}

      {/* Step 3: Form */}
      {step === "form" && (
        <div className="mx-4 mt-2 space-y-2">
          {/* Thumbnail */}
          <div className="flex gap-4 items-start mb-4">
            {(thumbUrl || preview) && (
              <div className="w-24 h-24 rounded-2xl overflow-hidden shadow-md flex-shrink-0">
                <img src={thumbUrl || preview!} alt="garment" className="w-full h-full object-cover" />
              </div>
            )}
            <div className="flex-1">
              <label className="text-sm font-semibold text-gray-600 dark:text-gray-300">Name</label>
              <input
                value={name}
                onChange={e => setName(e.target.value)}
                placeholder="e.g. Striped blue onesie"
                className="mt-1 w-full px-3 py-2 rounded-xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 text-sm focus:outline-none focus:ring-2 focus:ring-rose-300"
              />
            </div>
          </div>

          {/* Category */}
          <div className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-sm">
            <SingleChipRow
              label="Category"
              options={GARMENT_CATEGORIES}
              selected={category as typeof GARMENT_CATEGORIES[number] | null}
              onChange={v => setCategory(v)}
              required
              optionLabel={v => CATEGORY_LABELS[v] || v}
            />
          </div>

          {/* Size — required, not pre-filled */}
          <div className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-sm">
            <SingleChipRow
              label="Size"
              options={GARMENT_SIZE_ORDER}
              selected={sizeLabel as typeof GARMENT_SIZE_ORDER[number] | null}
              onChange={v => setSizeLabel(v)}
              required
            />
            {!sizeLabel && (
              <p className="text-xs text-amber-600 dark:text-amber-400 mt-2">
                ⚠ Size must be set manually — vision cannot guess it
              </p>
            )}
          </div>

          {/* Colors */}
          <div className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-sm">
            <p className="text-sm font-semibold text-gray-600 dark:text-gray-300 mb-2">Colors</p>
            <div className="flex flex-wrap gap-2 mb-3">
              {colors.map(c => (
                <button
                  key={c}
                  type="button"
                  onClick={() => setColors(colors.filter(x => x !== c))}
                  className="px-3 py-1 rounded-full text-sm bg-rose-100 text-rose-700 dark:bg-rose-900/30 dark:text-rose-300 flex items-center gap-1"
                >
                  {c} ×
                </button>
              ))}
            </div>
            <div className="flex gap-2">
              <input
                value={colorInput}
                onChange={e => setColorInput(e.target.value)}
                onKeyDown={e => e.key === "Enter" && addColor()}
                placeholder="Add color…"
                className="flex-1 px-3 py-1.5 rounded-xl bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 text-sm focus:outline-none"
              />
              <button type="button" onClick={addColor} className="px-3 py-1.5 bg-rose-400 text-white rounded-xl text-sm">Add</button>
            </div>
          </div>

          {/* Seasons */}
          <div className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-sm">
            <ChipRow
              label="Seasons"
              options={SEASON_OPTIONS as readonly string[]}
              selected={seasons}
              onChange={setSeasons}
            />
          </div>

          {/* Occasions */}
          <div className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-sm">
            <ChipRow
              label="Occasions"
              options={OCCASION_OPTIONS as readonly string[]}
              selected={occasionTags}
              onChange={setOccasionTags}
            />
          </div>

          {/* Optional fields */}
          <div className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-sm">
            <p className="text-sm font-semibold text-gray-600 dark:text-gray-300 mb-3">Optional</p>
            <div className="mb-3">
              <p className="text-xs text-gray-500 mb-1">Acquired via</p>
              <div className="flex gap-2">
                {ACQUIRED_OPTIONS.map(o => (
                  <button
                    key={o}
                    type="button"
                    onClick={() => setAcquiredVia(acquiredVia === o ? null : o)}
                    className={`px-3 py-1 rounded-full text-xs font-medium transition-all ${
                      acquiredVia === o
                        ? "bg-indigo-400 text-white"
                        : "bg-gray-100 dark:bg-gray-700 text-gray-500"
                    }`}
                  >
                    {o}
                  </button>
                ))}
              </div>
            </div>
            {acquiredVia === "gift" && (
              <div>
                <p className="text-xs text-gray-500 mb-1">Gift from</p>
                <input
                  value={giftFrom}
                  onChange={e => setGiftFrom(e.target.value)}
                  placeholder="e.g. Nani"
                  className="w-full px-3 py-2 rounded-xl bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 text-sm focus:outline-none"
                />
              </div>
            )}
          </div>

          {/* Action buttons */}
          <div className="pt-2 space-y-3">
            <Button
              fullWidth
              onClick={handleSave}
              loading={saving}
              disabled={!category || !sizeLabel || !childId}
              size="lg"
            >
              Save Garment
            </Button>
            {!sizeLabel && (
              <p className="text-center text-sm text-amber-600 dark:text-amber-400">
                Please select a size to save
              </p>
            )}
            <Button fullWidth variant="secondary" onClick={handleAddAnother} size="lg">
              + Add Another
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
