"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 { trackGarmentAdded } from "@/lib/analytics";
import { GARMENT_CATEGORIES, GARMENT_SIZE_ORDER } from "@/db/schema/wardrobe";

type Step = "capture" | "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);   // gallery picker
  const cameraRef = useRef<HTMLInputElement>(null);   // camera capture

  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);
  const [uploading, setUploading] = useState(false);    // photo still uploading to R2
  const [visionPending, setVisionPending] = useState(false); // AI analysis running in bg

  // 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("");

    // 1. Show local preview immediately and jump straight to the form.
    //    The user can start filling in size/occasions while the upload runs.
    const reader = new FileReader();
    reader.onload = ev => setPreview(ev.target?.result as string);
    reader.readAsDataURL(file);
    setStep("form");
    setUploading(true);
    setVisionPending(false);

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

    // 3. Fire vision AI in the background — do NOT await, form stays interactive.
    setVisionPending(true);
    fetch("/api/garments/tag", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ imageKey: ik }),
    })
      .then(r => r.ok ? r.json() : null)
      .then((vision: VisionResult | null) => {
        if (vision) {
          setVisionMetadata(vision);
          // Only pre-fill fields the user hasn't touched yet
          setName(n => n || vision.name || "");
          setCategory(c => c || vision.category || null);
          setColors(c => c.length ? c : (vision.colors || []));
          setSeasons(s => s.length ? s : (vision.seasons || []));
          setOccasionTags(t => t.length ? t : (vision.occasion_tags || []));
        }
      })
      .catch(() => {/* vision failure is non-fatal */})
      .finally(() => setVisionPending(false));
  };

  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);
      trackGarmentAdded();
      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("");
    setUploading(false);
    setVisionPending(false);
    if (fileRef.current)   fileRef.current.value   = "";
    if (cameraRef.current) cameraRef.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" && visionPending && (
          <span className="ml-auto text-xs text-amber-500 bg-amber-50 dark:bg-amber-900/20 px-2 py-1 rounded-full shadow-sm animate-pulse">
            🔍 AI tagging…
          </span>
        )}
        {step === "form" && !visionPending && visionMetadata && (
          <span className="ml-auto text-xs text-gray-400 bg-white dark:bg-gray-800 px-2 py-1 rounded-full shadow-sm">
            ✨ AI 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 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 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">Add a garment photo</p>
              <p className="text-sm text-gray-400 mt-1">Tip: flat-lay on a light surface for best AI tagging</p>
            </div>
            <div className="flex gap-3">
              <button
                type="button"
                onClick={() => cameraRef.current?.click()}
                className="flex items-center gap-2 px-5 py-2.5 bg-rose-400 text-white rounded-full text-sm font-medium shadow-sm active:scale-95 transition-transform"
              >
                📷 Camera
              </button>
              <button
                type="button"
                onClick={() => fileRef.current?.click()}
                className="flex items-center gap-2 px-5 py-2.5 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 rounded-full text-sm font-medium shadow-sm active:scale-95 transition-transform"
              >
                🖼 Gallery
              </button>
            </div>
          </div>
          {/* Gallery input — no capture attribute, Android shows full media picker */}
          <input
            ref={fileRef}
            type="file"
            accept="image/*"
            className="hidden"
            onChange={handleFileChange}
          />
          {/* Camera input — capture="environment" opens rear camera directly */}
          <input
            ref={cameraRef}
            type="file"
            accept="image/*"
            capture="environment"
            className="hidden"
            onChange={handleFileChange}
          />
        </div>
      )}

      {/* Step 2: Form (shown immediately after photo selected) */}
      {step === "form" && (
        <div className="mx-4 mt-2 space-y-2">
          {/* Thumbnail — shows upload spinner until R2 upload is done */}
          <div className="flex gap-4 items-start mb-4">
            {(thumbUrl || preview) && (
              <div className="relative 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" />
                {uploading && (
                  <div className="absolute inset-0 bg-black/40 flex items-center justify-center">
                    <div className="w-6 h-6 border-2 border-white border-t-transparent rounded-full animate-spin" />
                  </div>
                )}
              </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 || uploading}
              size="lg"
            >
              {uploading ? "Uploading photo…" : "Save Garment"}
            </Button>
            {uploading && (
              <p className="text-center text-sm text-gray-400">
                Photo uploading — you can pick size & tags while you wait
              </p>
            )}
            {!uploading && !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>
  );
}
