// app/vault/[uuid]/edit/page.tsx
"use client";

import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { useParams, useRouter } from "next/navigation";
import { useAuth } from "@/context/AuthContext";

type BuildItemDto = {
  id?: string;
  uuid?: string;
  slot?: string; // categoryId in your MVP
  position?: number | null;
  quantity?: number | null;
  productId?: string | null;
  productName?: string | null;
  productBrand?: string | null;
  productImageUrl?: string | null;
};

type BuildDto = {
  id: string;
  uuid: string;
  title: string;
  description?: string | null;
  isPublic?: boolean | null;
  createdAt?: string | null;
  updatedAt?: string | null;
  items?: BuildItemDto[] | null;

  // Option B: metadata fields on Build (or related BuildProfile)
  platform?: string | null;
  caliber?: string | null;
  // purpose?: string | null;
  buildClass?: string | null;
  tags?: string[] | null;
  coverImageUrl?: string | null;
};

const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080";

// -----------------------------
// Controlled vocab (platform + caliber)
// -----------------------------
const PLATFORM_OPTIONS = ["AR-15", "AR-10", "AR-9"] as const;
type PlatformOption = (typeof PLATFORM_OPTIONS)[number] | "";

/**
 * Keep this intentionally small and controlled for now:
 * - Only calibers relevant to AR-15 / AR-10 / AR-9
 * - Easy future expansion: add strings to the arrays below
 * - If you later want “canonical” values vs “labels”, we can switch to { value, label } objects.
 */
const CALIBERS_BY_PLATFORM: Record<
  Exclude<PlatformOption, "">,
  readonly string[]
> = {
  "AR-15": [
    "5.56 NATO",
    ".223 Rem",
    ".300 Blackout",
    "6.5 Grendel",
    "6mm ARC",
    "7.62x39",
    ".224 Valkyrie",
    "350 Legend",
    "6.8 SPC",
    "458 SOCOM",
  ],
  "AR-10": [
    "7.62 NATO",
    ".308 Win",
    "6.5 Creedmoor",
    "6mm Creedmoor",
    ".260 Rem",
    ".243 Win",
    "8.6 Blackout",
  ],
  "AR-9": ["9mm", "10mm", ".40 S&W", ".45 ACP"],
} as const;

type CaliberOption = string | "";

// -----------------------------
// Build Class (controlled list)
// -----------------------------
const BUILD_CLASS_OPTIONS = [
  "Home Defense",
  "Duty / Patrol",
  "Training",
  "Competition",
  "Hunting",
  "Range / Fun",
] as const;

type BuildClassOption = (typeof BUILD_CLASS_OPTIONS)[number] | "";

function fmt(d?: string | null) {
  if (!d) return "—";
  const dt = new Date(d);
  if (Number.isNaN(dt.getTime())) return d;
  return dt.toLocaleString();
}

function isUuid(v: string) {
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
    v
  );
}

export default function EditBuildPage() {
  const router = useRouter();
  const params = useParams();
  const { user, loading, getAuthHeaders } = useAuth();

  const uuid = String(params?.uuid ?? "");
  const authed = !!user;

  const headers = useMemo(() => getAuthHeaders(), [getAuthHeaders]);

  const [busy, setBusy] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const [build, setBuild] = useState<BuildDto | null>(null);

  // Editable submission/profile fields
  const [profile, setProfile] = useState<{
    title: string;
    description: string;
    isPublic: boolean;

    platform: PlatformOption;
    caliber: CaliberOption;
    buildClass: BuildClassOption;

    tagsText: string; // comma-separated for MVP
    coverImageUrl: string;
  } | null>(null);

  // Redirect to login if not authed
  useEffect(() => {
    if (!loading && !authed) router.replace("/login");
  }, [loading, authed, router]);

  // Load build
  useEffect(() => {
    if (loading || !authed) return;

    if (!uuid || !isUuid(uuid)) {
      setError("Invalid build id.");
      return;
    }

    let cancelled = false;

    (async () => {
      setBusy(true);
      setError(null);

      try {
        // NOTE: ownership / public checks happen server-side
        const res = await fetch(
          `${API_BASE_URL}/api/v1/builds/me/${encodeURIComponent(uuid)}`,
          {
            credentials: "include",
          }
        );

        if (!res.ok) {
          const txt = await res.text().catch(() => "");
          throw new Error(txt || `Load failed (${res.status})`);
        }

        const dto = (await res.json()) as BuildDto;
        if (cancelled) return;

        setBuild(dto);

        const normalizedPlatform: PlatformOption = PLATFORM_OPTIONS.includes(
          (dto.platform ?? "") as any
        )
          ? (dto.platform as PlatformOption)
          : "";

        const allowedCalibers = normalizedPlatform
          ? CALIBERS_BY_PLATFORM[normalizedPlatform]
          : [];

        const normalizedCaliber =
          dto.caliber && allowedCalibers.includes(dto.caliber)
            ? dto.caliber
            : "";

        setProfile({
          title: dto.title ?? "",
          description: dto.description ?? "",
          isPublic: !!dto.isPublic,

          platform: normalizedPlatform,
          caliber: normalizedCaliber,

          buildClass: (BUILD_CLASS_OPTIONS.includes(
            (dto.buildClass ?? "") as any
          )
            ? (dto.buildClass as any)
            : "") as BuildClassOption,

          tagsText: Array.isArray(dto.tags) ? dto.tags.join(", ") : "",
          coverImageUrl: dto.coverImageUrl ?? "",
        });
      } catch (e: any) {
        if (!cancelled) setError(e?.message || "Failed to load build");
      } finally {
        if (!cancelled) setBusy(false);
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [loading, authed, uuid, headers]);

  // Derived caliber options based on selected platform
  const caliberOptions = useMemo(() => {
    if (!profile?.platform) return [];
    return (
      CALIBERS_BY_PLATFORM[profile.platform as Exclude<PlatformOption, "">] ??
      []
    );
  }, [profile?.platform]);

  // If platform changes, ensure caliber is valid for that platform
  useEffect(() => {
    if (!profile) return;
    if (!profile.platform) return;

    const allowed =
      CALIBERS_BY_PLATFORM[profile.platform as Exclude<PlatformOption, "">] ??
      [];
    if (!profile.caliber) return;

    if (!allowed.includes(profile.caliber)) {
      setProfile((p) => (p ? { ...p, caliber: "" } : p));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [profile?.platform]); // intentionally only platform

  const save = async () => {
    if (!profile) return;
    if (!uuid || !isUuid(uuid)) return;

    const title = profile.title.trim();
    if (!title) {
      setError("Title is required.");
      return;
    }

    setSaving(true);
    setError(null);

    try {
      const payload = {
        title,
        description: profile.description?.trim() || null,
        isPublic: !!profile.isPublic,

        // Backend expects buildClass (not purpose)
        buildClass: profile.buildClass || null,

        caliber: profile.caliber || null,
        coverImageUrl: profile.coverImageUrl?.trim() || null,

        // Backend expects tags: string[]
        tags: profile.tagsText
          .split(",")
          .map((t) => t.trim())
          .filter(Boolean),

        // IMPORTANT: if your backend overwrites items when provided,
        // leave items undefined unless you intend to edit items here.
        // If your backend REQUIRES items, uncomment and map from build.items:
        // items: (build?.items ?? []).map((it) => ({
        //   productId: it.productId ? Number(it.productId) : null,
        //   slot: it.slot ?? "",
        //   position: it.position ?? 0,
        //   quantity: it.quantity ?? 1,
        // })).filter((it) => it.productId && it.slot),
      };

      const res = await fetch(
        `${API_BASE_URL}/api/v1/builds/me/${encodeURIComponent(uuid)}`,
        {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
            ...headers,
          },
          credentials: "include",
          body: JSON.stringify(payload),
        }
      );

      if (!res.ok) {
        const txt = await res.text().catch(() => "");
        throw new Error(txt || `Save failed (${res.status})`);
      }

      const updated = (await res.json().catch(() => null)) as BuildDto | null;
      if (updated?.uuid) setBuild(updated);

      router.replace("/vault");
    } catch (e: any) {
      setError(e?.message || "Save failed");
    } finally {
      setSaving(false);
    }
  };

  if (loading || busy) {
    return (
      <div className="mx-auto max-w-6xl px-4 py-6">
        <div className="text-sm opacity-70">Loading…</div>
      </div>
    );
  }

  if (!authed) return null;

  return (
    <div className="mx-auto max-w-6xl px-4 py-6">
      <div className="mb-6 flex items-start justify-between gap-4">
        <div className="min-w-0">
          <h1 className="text-2xl font-semibold truncate">Edit Build</h1>
          <div className="mt-1 text-xs opacity-70 font-mono truncate">
            {uuid}
          </div>
          <div className="mt-1 text-xs opacity-60">
            Updated: {fmt(build?.updatedAt)}
          </div>
        </div>

        <div className="flex items-center gap-3">
          <Link
            prefetch={false}
            href={`/builder?load=${encodeURIComponent(uuid)}`}
            className="rounded-md border border-white/10 bg-white/5 px-3 py-1.5 text-sm hover:bg-white/10"
          >
            Open in Builder
          </Link>
          <Link href="/vault" className="text-sm opacity-80 hover:underline">
            ← Vault
          </Link>
        </div>
      </div>

      {error && (
        <div className="mb-4 rounded-xl border border-red-500/30 bg-red-500/10 p-3 text-sm">
          {error}
        </div>
      )}

      {!profile ? (
        <div className="rounded-xl border border-white/10 bg-white/5 p-4 text-sm opacity-70">
          No build loaded.
        </div>
      ) : (
        <div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
          {/* Left: form */}
          <div className="lg:col-span-2 rounded-xl border border-white/10 bg-white/5 p-4">
            <div className="mb-4">
              <div className="text-sm font-medium">Submission Details</div>
              <div className="text-xs opacity-70">
                Controlled fields keep the community feed clean + filterable.
              </div>
            </div>

            <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
              {/* Title */}
              <div className="md:col-span-2">
                <label className="block text-xs font-medium text-white/70">
                  Title
                </label>
                <input
                  value={profile.title}
                  onChange={(e) =>
                    setProfile((p) => (p ? { ...p, title: e.target.value } : p))
                  }
                  className="mt-1 w-full rounded-md border border-white/10 bg-black/30 px-3 py-2 text-sm text-white outline-none focus:ring-1 focus:ring-amber-400/60"
                  placeholder='e.g. "Budget 16” General Purpose AR-15"'
                />
              </div>

              {/* Platform */}
              <div>
                <label className="block text-xs font-medium text-white/70">
                  Platform
                </label>
                <select
                  value={profile.platform}
                  onChange={(e) =>
                    setProfile((p) =>
                      p
                        ? {
                            ...p,
                            platform: e.target.value as PlatformOption,
                          }
                        : p
                    )
                  }
                  className="mt-1 w-full rounded-md border border-white/10 bg-black/30 px-3 py-2 text-sm text-white outline-none focus:ring-1 focus:ring-amber-400/60"
                >
                  <option value="">Select…</option>
                  {PLATFORM_OPTIONS.map((p) => (
                    <option key={p} value={p}>
                      {p}
                    </option>
                  ))}
                </select>
                <div className="mt-1 text-xs text-white/40">
                  Controlled list (prevents messy feed data).
                </div>
              </div>

              {/* Caliber */}
              <div>
                <label className="block text-xs font-medium text-white/70">
                  Caliber
                </label>
                <select
                  value={profile.caliber}
                  onChange={(e) =>
                    setProfile((p) =>
                      p ? { ...p, caliber: e.target.value as CaliberOption } : p
                    )
                  }
                  disabled={!profile.platform}
                  className={`mt-1 w-full rounded-md border border-white/10 bg-black/30 px-3 py-2 text-sm text-white outline-none focus:ring-1 focus:ring-amber-400/60 ${
                    !profile.platform ? "opacity-50 cursor-not-allowed" : ""
                  }`}
                >
                  <option value="">
                    {profile.platform ? "Select…" : "Select platform first…"}
                  </option>
                  {caliberOptions.map((c) => (
                    <option key={c} value={c}>
                      {c}
                    </option>
                  ))}
                </select>
                <div className="mt-1 text-xs text-white/40">
                  Options are tied to platform. Update{" "}
                  <span className="font-mono">CALIBERS_BY_PLATFORM</span> to add
                  more.
                </div>
              </div>

              {/* Build Class */}
              <div>
                <label className="block text-xs font-medium text-white/70">
                  Build Class
                </label>
                <select
                  value={profile.buildClass}
                  onChange={(e) =>
                    setProfile((p) =>
                      p
                        ? {
                            ...p,
                            buildClass: e.target.value as BuildClassOption,
                          }
                        : p
                    )
                  }
                  className="mt-1 w-full rounded-md border border-white/10 bg-black/30 px-3 py-2 text-sm text-white outline-none focus:ring-1 focus:ring-amber-400/60"
                >
                  <option value="">Select…</option>
                  {BUILD_CLASS_OPTIONS.map((c) => (
                    <option key={c} value={c}>
                      {c}
                    </option>
                  ))}
                </select>
              </div>

              {/* Tags */}
              <div>
                <label className="block text-xs font-medium text-white/70">
                  Tags
                </label>
                <input
                  value={profile.tagsText}
                  onChange={(e) =>
                    setProfile((p) =>
                      p ? { ...p, tagsText: e.target.value } : p
                    )
                  }
                  className="mt-1 w-full rounded-md border border-white/10 bg-black/30 px-3 py-2 text-sm text-white outline-none focus:ring-1 focus:ring-amber-400/60"
                  placeholder="budget, general purpose, suppressed"
                />
                <div className="mt-1 text-xs text-white/40">
                  Comma-separated for MVP.
                </div>
              </div>

              {/* Cover image URL */}
              <div className="md:col-span-2">
                <label className="block text-xs font-medium text-white/70">
                  Cover Image URL
                </label>
                <input
                  value={profile.coverImageUrl}
                  onChange={(e) =>
                    setProfile((p) =>
                      p ? { ...p, coverImageUrl: e.target.value } : p
                    )
                  }
                  className="mt-1 w-full rounded-md border border-white/10 bg-black/30 px-3 py-2 text-sm text-white outline-none focus:ring-1 focus:ring-amber-400/60"
                  placeholder="https://…"
                />
                <div className="mt-1 text-xs text-white/40">
                  Later we’ll replace this with uploads.
                </div>
              </div>

              {/* Description */}
              <div className="md:col-span-2">
                <label className="block text-xs font-medium text-white/70">
                  Description
                </label>
                <textarea
                  value={profile.description}
                  onChange={(e) =>
                    setProfile((p) =>
                      p ? { ...p, description: e.target.value } : p
                    )
                  }
                  rows={5}
                  className="mt-1 w-full rounded-md border border-white/10 bg-black/30 px-3 py-2 text-sm text-white outline-none focus:ring-1 focus:ring-amber-400/60"
                  placeholder="What’s the goal of this build? Any notes, constraints, lessons learned…"
                />
              </div>

              {/* Public toggle */}
              <div className="md:col-span-2 flex items-center justify-between rounded-md border border-white/10 bg-black/20 px-3 py-2">
                <div>
                  <div className="text-sm font-medium">Make Public</div>
                  <div className="text-xs opacity-70">
                    When enabled, this build can appear in the community feed
                    later.
                  </div>
                </div>
                <input
                  type="checkbox"
                  checked={!!profile.isPublic}
                  onChange={(e) =>
                    setProfile((p) =>
                      p ? { ...p, isPublic: e.target.checked } : p
                    )
                  }
                  className="h-5 w-5 accent-amber-400"
                />
              </div>
            </div>

            {/* Actions */}
            <div className="mt-6 flex items-center justify-end gap-3">
              <Link
                href="/vault"
                className="text-sm opacity-80 hover:underline"
              >
                Cancel
              </Link>
              <button
                type="button"
                onClick={save}
                disabled={saving}
                className={`rounded-md px-4 py-2 text-sm font-semibold ${
                  saving
                    ? "bg-white/10 text-white/60 cursor-not-allowed"
                    : "bg-amber-400 text-black hover:bg-amber-300"
                }`}
              >
                {saving ? "Saving…" : "Save Changes"}
              </button>
            </div>
          </div>

          {/* Right: preview */}
          <div className="rounded-xl border border-white/10 bg-white/5 p-4">
            <div className="mb-3">
              <div className="text-sm font-medium">Preview</div>
              <div className="text-xs opacity-70">
                This is roughly what the community card will show.
              </div>
            </div>

            <div className="rounded-lg border border-white/10 bg-black/30 p-3">
              <div className="text-sm font-semibold truncate">
                {profile.title || "Untitled Build"}
              </div>

              <div className="mt-2 flex flex-wrap gap-2 text-xs">
                <span className="rounded-full border border-white/10 bg-white/5 px-2 py-1">
                  {profile.platform || "—"}
                </span>
                <span className="rounded-full border border-white/10 bg-white/5 px-2 py-1">
                  {profile.caliber || "—"}
                </span>
                <span className="rounded-full border border-white/10 bg-white/5 px-2 py-1">
                  {profile.buildClass || "—"}
                </span>
              </div>

              {profile.tagsText?.trim() ? (
                <div className="mt-2 text-xs opacity-80">
                  Tags:{" "}
                  {profile.tagsText
                    .split(",")
                    .map((t) => t.trim())
                    .filter(Boolean)
                    .slice(0, 6)
                    .join(", ")}
                </div>
              ) : null}

              {profile.description?.trim() ? (
                <div className="mt-3 text-xs opacity-80 line-clamp-5">
                  {profile.description}
                </div>
              ) : (
                <div className="mt-3 text-xs opacity-50">
                  Add a description to help people understand the “why”.
                </div>
              )}

              <div className="mt-3 text-[11px] opacity-60">
                Build UUID: <span className="font-mono">{uuid}</span>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
