"use client";

import { useCallback, useEffect, useReducer, useRef, useSyncExternalStore, useEffectEvent } from "react";
import Image from "next/image";
import { createPortal } from "react-dom";

export type ProductFormModalProps = {
  open: boolean;
  mode: "add" | "edit";
  onClose: () => void;
  onSubmit: (values: ProductFormValues) => Promise<{ success: boolean; error?: string }>;
  /** Defaults / initial values (edit mode passes the current product) */
  initial?: Partial<ProductFormValues>;
  /** List of selectable brands (only shown to platform admins) */
  brands?: { id: string; name: string }[];
  /** When true the brand picker is hidden and the admin's brand is used */
  lockBrand?: boolean;
  /** Hard-locked brand id (for brand_admin / store_employee) */
  lockedBrandId?: string;
  /** Pre-uploaded image URL (edit mode) */
  initialImageUrl?: string | null;
  /** Server action: upload a file and return the public URL */
  onUploadImage: (file: File) => Promise<{ success: boolean; imageUrl?: string; error?: string }>;
};

export type ProductFormValues = {
  name: string;
  description: string;
  price: string;
  type: "pickup" | "wholesale" | "subscription";
  brand_id: string;
  active: boolean;
  is_taxable: boolean;
  image_url: string | null;
  available_from?: string | null;
  available_until?: string | null;
};

const TYPE_OPTIONS: Array<{
  value: ProductFormValues["type"];
  label: string;
  italic: string;
  icon: React.ReactNode;
}> = [
  {
    value: "pickup",
    label: "Pickup",
    italic: "Farm & stops",
    icon: (
      <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.6} strokeLinecap="round" strokeLinejoin="round">
        <path d="M3 9l1.5-4h15L21 9" />
        <path d="M3 9v11a1 1 0 001 1h16a1 1 0 001-1V9" />
        <path d="M3 9h18" />
        <path d="M9 14h6" />
      </svg>
    ),
  },
  {
    value: "wholesale",
    label: "Wholesale",
    italic: "B2B portal",
    icon: (
      <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.6} strokeLinecap="round" strokeLinejoin="round">
        <path d="M3 7h18l-2 12H5L3 7z" />
        <path d="M8 7V5a4 4 0 018 0v2" />
      </svg>
    ),
  },
  {
    value: "subscription",
    label: "Subscription",
    italic: "Recurring",
    icon: (
      <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.6} strokeLinecap="round" strokeLinejoin="round">
        <path d="M21 12a9 9 0 11-3-6.7" />
        <path d="M21 4v5h-5" />
      </svg>
    ),
  },
];

const EMPTY_BRANDS: { id: string; name: string }[] = [];

type State = {
  name: string;
  description: string;
  price: string;
  type: ProductFormValues["type"];
  brandId: string;
  active: boolean;
  isTaxable: boolean;
  availableFrom: string;
  availableUntil: string;
  imagePreview: string | null;
  imageUrlRef: string | null;
  uploading: boolean;
  uploadError: string | null;
  isDrag: boolean;
  saving: boolean;
  error: string | null;
};

type Action =
  | { type: "SET_NAME"; value: string }
  | { type: "SET_DESCRIPTION"; value: string }
  | { type: "SET_PRICE"; value: string }
  | { type: "SET_TYPE"; value: ProductFormValues["type"] }
  | { type: "SET_BRAND_ID"; value: string }
  | { type: "TOGGLE_ACTIVE" }
  | { type: "TOGGLE_TAXABLE" }
  | { type: "SET_AVAILABLE_FROM"; value: string }
  | { type: "SET_AVAILABLE_UNTIL"; value: string }
  | { type: "CLEAR_AVAILABILITY" }
  | { type: "SET_IMAGE_PREVIEW"; value: string | null }
  | { type: "SET_IMAGE_URL_REF"; value: string | null }
  | { type: "CLEAR_IMAGE" }
  | { type: "SET_UPLOADING"; value: boolean }
  | { type: "SET_UPLOAD_ERROR"; value: string | null }
  | { type: "SET_DRAG"; value: boolean }
  | { type: "SET_SAVING"; value: boolean }
  | { type: "SET_ERROR"; value: string | null };

function makeInitialState(
  initial?: Partial<ProductFormValues>,
  lockedBrandId?: string,
  brands?: { id: string; name: string }[],
  initialImageUrl?: string | null
): State {
  return {
    name: initial?.name ?? "",
    description: initial?.description ?? "",
    price: initial?.price ?? "",
    type: (initial?.type as ProductFormValues["type"]) ?? "pickup",
    brandId: initial?.brand_id ?? lockedBrandId ?? brands?.[0]?.id ?? "",
    active: initial?.active ?? true,
    isTaxable: initial?.is_taxable ?? true,
    availableFrom: initial?.available_from ? initial.available_from.split("T")[0] : "",
    availableUntil: initial?.available_until ? initial.available_until.split("T")[0] : "",
    imagePreview: initialImageUrl ?? null,
    imageUrlRef: initialImageUrl ?? null,
    uploading: false,
    uploadError: null,
    isDrag: false,
    saving: false,
    error: null,
  };
}

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_NAME":
      return { ...state, name: action.value };
    case "SET_DESCRIPTION":
      return { ...state, description: action.value };
    case "SET_PRICE":
      return { ...state, price: action.value };
    case "SET_TYPE":
      return { ...state, type: action.value };
    case "SET_BRAND_ID":
      return { ...state, brandId: action.value };
    case "TOGGLE_ACTIVE":
      return { ...state, active: !state.active };
    case "TOGGLE_TAXABLE":
      return { ...state, isTaxable: !state.isTaxable };
    case "SET_AVAILABLE_FROM":
      return { ...state, availableFrom: action.value };
    case "SET_AVAILABLE_UNTIL":
      return { ...state, availableUntil: action.value };
    case "CLEAR_AVAILABILITY":
      return { ...state, availableFrom: "", availableUntil: "" };
    case "SET_IMAGE_PREVIEW":
      return { ...state, imagePreview: action.value };
    case "SET_IMAGE_URL_REF":
      return { ...state, imageUrlRef: action.value };
    case "CLEAR_IMAGE":
      return { ...state, imagePreview: null, imageUrlRef: null };
    case "SET_UPLOADING":
      return { ...state, uploading: action.value };
    case "SET_UPLOAD_ERROR":
      return { ...state, uploadError: action.value };
    case "SET_DRAG":
      return { ...state, isDrag: action.value };
    case "SET_SAVING":
      return { ...state, saving: action.value };
    case "SET_ERROR":
      return { ...state, error: action.value };
  }
}

export default function ProductFormModal({
  open,
  mode,
  onClose,
  onSubmit,
  initial,
  brands = EMPTY_BRANDS,
  lockBrand = false,
  lockedBrandId = "",
  initialImageUrl = null,
  onUploadImage,
}: ProductFormModalProps) {
  // Form state — lazy initializers read the latest `initial` / `initialImageUrl`
  // props. The parent (ProductsClient) supplies a `key` derived from
  // `editingProduct?.id` so changing the product under edit triggers a
  // remount instead of a state-reset effect.
  const [state, dispatch] = useReducer(
    reducer,
    { initial, lockedBrandId, brands, initialImageUrl },
    (args) => makeInitialState(args.initial, args.lockedBrandId, args.brands, args.initialImageUrl)
  );

  const fileInputRef = useRef<HTMLInputElement>(null);

  // SSR-safe mounted flag via useSyncExternalStore so the first render
  // already reflects "we are on the client" — no flash of an empty
  // portal, no `useEffect(() => setMounted(true), [])` to flag.
  const mounted = useSyncExternalStore(
    () => () => {},
    () => true,
    () => false,
  );

  // Body scroll lock + escape key
  // Native <dialog> handles both focus trapping and ESC; we just open
  // it with showModal() and forward the cancel event to onClose so the
  // parent's React state stays in sync with the native close behavior.
  const dialogRef = useRef<HTMLDialogElement>(null);

  const onCloseEvent = useEffectEvent(() => {
    onClose();
  });

  useEffect(() => {
    const dialog = dialogRef.current;
    if (!dialog) return;
    if (!dialog.open) dialog.showModal();
    const onCancel = (e: Event) => {
      e.preventDefault();
      onCloseEvent();
    };
    dialog.addEventListener("cancel", onCancel);
    return () => {
      dialog.removeEventListener("cancel", onCancel);
    };
  }, [open]);

  const handleFile = useCallback(
    async (file: File) => {
      const validTypes = ["image/png", "image/jpeg", "image/webp"];
      if (!validTypes.includes(file.type)) {
        dispatch({ type: "SET_UPLOAD_ERROR", value: "PNG, JPEG, or WebP only." });
        return;
      }
      if (file.size > 5 * 1024 * 1024) {
        dispatch({ type: "SET_UPLOAD_ERROR", value: "File must be under 5MB." });
        return;
      }
      dispatch({ type: "SET_UPLOAD_ERROR", value: null });
      dispatch({ type: "SET_UPLOADING", value: true });

      // Local preview first
      const localUrl = URL.createObjectURL(file);
      dispatch({ type: "SET_IMAGE_PREVIEW", value: localUrl });

      const result = await onUploadImage(file);
      dispatch({ type: "SET_UPLOADING", value: false });

      if (result.success && result.imageUrl) {
        dispatch({ type: "SET_IMAGE_URL_REF", value: result.imageUrl });
        dispatch({ type: "SET_IMAGE_PREVIEW", value: result.imageUrl });
        URL.revokeObjectURL(localUrl);
      } else {
        dispatch({ type: "SET_UPLOAD_ERROR", value: result.error ?? "Upload failed." });
        dispatch({ type: "SET_IMAGE_PREVIEW", value: state.imageUrlRef }); // revert
      }
    },
    [onUploadImage, state.imageUrlRef]
  );

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    dispatch({ type: "SET_ERROR", value: null });

    if (!state.name.trim()) {
      dispatch({ type: "SET_ERROR", value: "Product name is required." });
      return;
    }
    if (!state.price || isNaN(parseFloat(state.price)) || parseFloat(state.price) < 0) {
      dispatch({ type: "SET_ERROR", value: "Valid price is required." });
      return;
    }
    if (!lockBrand && !state.brandId) {
      dispatch({ type: "SET_ERROR", value: "Please select a brand." });
      return;
    }

    dispatch({ type: "SET_SAVING", value: true });
    const res = await onSubmit({
      name: state.name.trim(),
      description: state.description.trim(),
      price: state.price,
      type: state.type,
      brand_id: lockBrand ? lockedBrandId : state.brandId,
      active: state.active,
      is_taxable: state.isTaxable,
      image_url: state.imageUrlRef,
      available_from: state.availableFrom ? new Date(state.availableFrom).toISOString() : null,
      available_until: state.availableUntil ? new Date(state.availableUntil).toISOString() : null,
    });
    dispatch({ type: "SET_SAVING", value: false });

    if (!res.success) {
      dispatch({ type: "SET_ERROR", value: res.error ?? "Something went wrong." });
      return;
    }
    onClose();
  }

  if (!mounted || !open) return null;

  return createPortal(
    <ProductFormDialog
      state={state}
      mode={mode}
      brands={brands}
      lockBrand={lockBrand}
      lockedBrandId={lockedBrandId}
      initialName={initial?.name}
      dialogRef={dialogRef}
      fileInputRef={fileInputRef}
      onClose={onClose}
      onNameChange={(v) => dispatch({ type: "SET_NAME", value: v })}
      onDescriptionChange={(v) => dispatch({ type: "SET_DESCRIPTION", value: v })}
      onPriceChange={(v) => dispatch({ type: "SET_PRICE", value: v })}
      onBrandChange={(v) => dispatch({ type: "SET_BRAND_ID", value: v })}
      onTypeChange={(v) => dispatch({ type: "SET_TYPE", value: v })}
      onToggleActive={() => dispatch({ type: "TOGGLE_ACTIVE" })}
      onToggleTaxable={() => dispatch({ type: "TOGGLE_TAXABLE" })}
      onAvailableFromChange={(v) => dispatch({ type: "SET_AVAILABLE_FROM", value: v })}
      onAvailableUntilChange={(v) => dispatch({ type: "SET_AVAILABLE_UNTIL", value: v })}
      onClearAvailability={() => dispatch({ type: "CLEAR_AVAILABILITY" })}
      onDragEnter={() => dispatch({ type: "SET_DRAG", value: true })}
      onDragOver={() => dispatch({ type: "SET_DRAG", value: true })}
      onDragLeave={() => dispatch({ type: "SET_DRAG", value: false })}
      onDrop={(file) => {
        dispatch({ type: "SET_DRAG", value: false });
        void handleFile(file);
      }}
      onFileInput={(file) => void handleFile(file)}
      onClearImage={() => dispatch({ type: "CLEAR_IMAGE" })}
      onSubmit={handleSubmit}
    />,
    document.body
  );
}

type DialogProps = {
  state: State;
  mode: "add" | "edit";
  brands: { id: string; name: string }[];
  lockBrand: boolean;
  lockedBrandId: string;
  initialName?: string;
  dialogRef: React.RefObject<HTMLDialogElement | null>;
  fileInputRef: React.RefObject<HTMLInputElement | null>;
  onClose: () => void;
  onNameChange: (v: string) => void;
  onDescriptionChange: (v: string) => void;
  onPriceChange: (v: string) => void;
  onBrandChange: (v: string) => void;
  onTypeChange: (v: ProductFormValues["type"]) => void;
  onToggleActive: () => void;
  onToggleTaxable: () => void;
  onAvailableFromChange: (v: string) => void;
  onAvailableUntilChange: (v: string) => void;
  onClearAvailability: () => void;
  onDragEnter: () => void;
  onDragOver: () => void;
  onDragLeave: () => void;
  onDrop: (file: File) => void;
  onFileInput: (file: File) => void;
  onClearImage: () => void;
  onSubmit: (e: React.FormEvent) => void;
};

function ProductFormDialog({
  state,
  mode,
  brands,
  lockBrand,
  lockedBrandId,
  initialName,
  dialogRef,
  fileInputRef,
  onClose,
  onNameChange,
  onDescriptionChange,
  onPriceChange,
  onBrandChange,
  onTypeChange,
  onToggleActive,
  onToggleTaxable,
  onAvailableFromChange,
  onAvailableUntilChange,
  onClearAvailability,
  onDragEnter,
  onDragOver,
  onDragLeave,
  onDrop,
  onFileInput,
  onClearImage,
  onSubmit,
}: DialogProps) {
  const showBrandPicker = !lockBrand;
  const lockedBrandName = brands.find((b) => b.id === lockedBrandId)?.name ?? lockedBrandId;

  return (
    <dialog
      ref={dialogRef}
      aria-label={mode === "add" ? "Add product" : "Edit product"}
      className="m-0 p-0 w-full h-full max-w-none max-h-full bg-transparent"
      style={{ backgroundColor: "transparent" }}
    >
      <div
        className="fixed inset-0 z-[80] flex items-center justify-center p-3 sm:p-6 atelier-backdrop"
        style={{
          backgroundColor: "color-mix(in srgb, var(--admin-text-primary) 55%, transparent)",
          backdropFilter: "blur(8px)",
          WebkitBackdropFilter: "blur(8px)",
        }}
      >
        <div
          className="atelier-enter atelier-canvas relative w-full max-w-5xl max-h-[calc(100vh-1.5rem)] sm:max-h-[calc(100vh-3rem)] rounded-2xl flex flex-col overflow-hidden border border-[var(--admin-border)]"
          style={{ boxShadow: "0 30px 80px -20px color-mix(in srgb, var(--admin-text-primary) 45%, transparent)" }}
        >
          {/* grain overlay */}
          <div className="atelier-grain" aria-hidden />

          {/* HEADER */}
          <FormHeader mode={mode} initialName={initialName} onClose={onClose} />

          <div className="relative shrink-0 px-6 sm:px-10">
            <hr className="atelier-rule" />
          </div>

          {/* BODY — two columns */}
          <form
            onSubmit={onSubmit}
            className="relative flex-1 overflow-y-auto"
            onDragEnter={(e) => {
              e.preventDefault();
              onDragEnter();
            }}
          >
            <div className="grid grid-cols-1 lg:grid-cols-[minmax(0,5fr)_minmax(0,7fr)] gap-0">
              {/* LEFT — Image hero */}
              <ImageHeroColumn
                state={state}
                fileInputRef={fileInputRef}
                onDragOver={onDragOver}
                onDragLeave={onDragLeave}
                onDrop={onDrop}
                onFileInput={onFileInput}
                onClearImage={onClearImage}
              />

              {/* RIGHT — Form fields */}
              <FormFieldsColumn
                state={state}
                mode={mode}
                showBrandPicker={showBrandPicker}
                brands={brands}
                lockedBrandName={lockedBrandName}
                onNameChange={onNameChange}
                onDescriptionChange={onDescriptionChange}
                onPriceChange={onPriceChange}
                onBrandChange={onBrandChange}
                onTypeChange={onTypeChange}
                onToggleActive={onToggleActive}
                onToggleTaxable={onToggleTaxable}
                onAvailableFromChange={onAvailableFromChange}
                onAvailableUntilChange={onAvailableUntilChange}
                onClearAvailability={onClearAvailability}
              />
            </div>
          </form>

          {/* FOOTER */}
          <FormFooter
            state={state}
            mode={mode}
            onClose={onClose}
            onSubmit={onSubmit}
          />
        </div>
      </div>
    </dialog>
  );
}

function FormHeader({
  mode,
  initialName,
  onClose,
}: {
  mode: "add" | "edit";
  initialName?: string;
  onClose: () => void;
}) {
  return (
    <div className="relative shrink-0 px-6 sm:px-10 pt-6 sm:pt-8 pb-5 sm:pb-6">
      <div className="flex items-start justify-between gap-4">
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2.5 mb-3">
            <span className="atelier-section-num">
              {mode === "add" ? "Nouveau" : "Mise à jour"} · MMXXVI
            </span>
          </div>
          <h2 className="atelier-title text-3xl sm:text-4xl md:text-5xl">
            {mode === "add" ? (
              <>
                Add a <span className="atelier-italic">product</span>
              </>
            ) : (
              <>
                Edit <span className="atelier-italic">{initialName || "product"}</span>
              </>
            )}
          </h2>
          <p className="atelier-italic mt-2 text-sm sm:text-[15px] max-w-md leading-relaxed">
            {mode === "add"
              ? "Compose a new entry for the harvest catalog — every detail, like a recipe."
              : "Refine the details of this entry. The catalog is a living record."}
          </p>
        </div>
        <button
          type="button"
          onClick={onClose}
          className="shrink-0 flex h-9 w-9 items-center justify-center rounded-full transition-all duration-200 hover:bg-stone-900 hover:text-white text-stone-500"
          aria-label="Close"
        >
          <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      </div>
    </div>
  );
}

function ImageHeroColumn({
  state,
  fileInputRef,
  onDragOver,
  onDragLeave,
  onDrop,
  onFileInput,
  onClearImage,
}: {
  state: State;
  fileInputRef: React.RefObject<HTMLInputElement | null>;
  onDragOver: () => void;
  onDragLeave: () => void;
  onDrop: (file: File) => void;
  onFileInput: (file: File) => void;
  onClearImage: () => void;
}) {
  return (
    <div className="relative px-6 sm:px-10 pt-6 sm:pt-8 pb-6 lg:border-r border-stone-200/60 lg:pr-8">
      <div className="atelier-section-num mb-4">01 · Media</div>

      <label
        onDragOver={(e) => {
          e.preventDefault();
          onDragOver();
        }}
        onDragLeave={(e) => {
          if (e.currentTarget === e.target) onDragLeave();
        }}
        onDrop={(e) => {
          e.preventDefault();
          const file = e.dataTransfer.files?.[0];
          if (file) onDrop(file);
        }}
        className={[
          "atelier-drop",
          state.isDrag ? "is-drag" : "",
          state.uploadError ? "is-error" : "",
          state.imagePreview ? "has-image" : "",
        ].join(" ")}
      >
        {/* status pill */}
        <div
          className={[
            "atelier-status-pill",
            state.imagePreview ? "" : "is-empty",
          ].join(" ")}
        >
          <span className="atelier-dot" />
          {state.imagePreview
            ? state.uploading
              ? "Uploading"
              : "Image set"
            : "No image yet"}
        </div>

        {state.uploading ? (
          <div className="flex flex-col items-center gap-3">
            <div className="h-6 w-6 rounded-full border-2 border-stone-300 border-t-[var(--admin-primary)] animate-spin" />
            <p className="atelier-drop-title">Pouring into the cellar…</p>
          </div>
        ) : state.imagePreview ? (
          <div className="absolute inset-0 p-3 sm:p-4">
            <div className="relative h-full w-full">
              <Image
                src={state.imagePreview}
                alt="Product preview"
                fill
                sizes="(max-width: 640px) 100vw, 50vw"
                style={{ objectFit: "contain" }}
                className="rounded-md"
              />
            </div>
            <button
              type="button"
              onClick={(e) => {
                e.stopPropagation();
                onClearImage();
              }}
              className="absolute bottom-4 left-1/2 -translate-x-1/2 inline-flex items-center gap-1.5 rounded-full bg-stone-900/85 backdrop-blur-sm px-3 py-1.5 text-[11px] font-mono uppercase tracking-wider text-white hover:bg-stone-900 transition-colors"
            >
              <svg className="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
              </svg>
              Remove
            </button>
          </div>
        ) : (
          <>
            {/* ornamental drop zone content */}
            <svg
              className="h-10 w-10 text-[var(--admin-primary)]/70"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              strokeWidth={1.2}
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="M12 3v13" />
              <path d="M7 8l5-5 5 5" />
              <path d="M4 16v3a2 2 0 002 2h12a2 2 0 002-2v-3" />
              <circle cx="12" cy="20" r="0.8" fill="currentColor" />
            </svg>
            <p className="atelier-drop-eyebrow">Drag &amp; drop</p>
            <p className="atelier-drop-title">
              or click to choose<br />a harvest portrait
            </p>
            <p className="atelier-drop-hint">PNG · JPEG · WebP · 5MB max</p>
          </>
        )}

        <input aria-label="File upload"
          ref={fileInputRef}
          type="file"
          accept="image/png,image/jpeg,image/webp"
          className="sr-only"
          onChange={(e) => {
            const file = e.target.files?.[0];
            if (file) onFileInput(file);
            e.target.value = "";
          }}
        />
      </label>

      {state.uploadError && (
        <p className="mt-3 atelier-hint" style={{ color: "var(--admin-danger)" }}>
          {state.uploadError}
        </p>
      )}
    </div>
  );
}

function FormFieldsColumn({
  state,
  showBrandPicker,
  brands,
  lockedBrandName,
  onNameChange,
  onDescriptionChange,
  onPriceChange,
  onBrandChange,
  onTypeChange,
  onToggleActive,
  onToggleTaxable,
  onAvailableFromChange,
  onAvailableUntilChange,
  onClearAvailability,
}: {
  state: State;
  mode: "add" | "edit";
  showBrandPicker: boolean;
  brands: { id: string; name: string }[];
  lockedBrandName: string;
  onNameChange: (v: string) => void;
  onDescriptionChange: (v: string) => void;
  onPriceChange: (v: string) => void;
  onBrandChange: (v: string) => void;
  onTypeChange: (v: ProductFormValues["type"]) => void;
  onToggleActive: () => void;
  onToggleTaxable: () => void;
  onAvailableFromChange: (v: string) => void;
  onAvailableUntilChange: (v: string) => void;
  onClearAvailability: () => void;
}) {
  return (
    <div className="px-6 sm:px-10 pt-6 sm:pt-8 pb-6 lg:pl-10 space-y-7 atelier-stagger">
      {state.error && (
        <div className="atelier-error">
          <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          <span>{state.error}</span>
        </div>
      )}

      {/* 02 IDENTITY */}
      <IdentitySection
        name={state.name}
        description={state.description}
        onNameChange={onNameChange}
        onDescriptionChange={onDescriptionChange}
      />

      {/* 03 COMMERCE */}
      <CommerceSection
        price={state.price}
        type={state.type}
        showBrandPicker={showBrandPicker}
        brands={brands}
        brandId={state.brandId}
        lockedBrandName={lockedBrandName}
        onPriceChange={onPriceChange}
        onBrandChange={onBrandChange}
        onTypeChange={onTypeChange}
      />

      {/* 04 SETTINGS */}
      <SettingsSection
        active={state.active}
        isTaxable={state.isTaxable}
        availableFrom={state.availableFrom}
        availableUntil={state.availableUntil}
        onToggleActive={onToggleActive}
        onToggleTaxable={onToggleTaxable}
        onAvailableFromChange={onAvailableFromChange}
        onAvailableUntilChange={onAvailableUntilChange}
        onClearAvailability={onClearAvailability}
      />
    </div>
  );
}

function IdentitySection({
  name,
  description,
  onNameChange,
  onDescriptionChange,
}: {
  name: string;
  description: string;
  onNameChange: (v: string) => void;
  onDescriptionChange: (v: string) => void;
}) {
  return (
    <section>
      <div className="flex items-baseline justify-between mb-4">
        <div className="atelier-section-num">02 · Identity</div>
      </div>

      <div>
        <label
          htmlFor="atelier-name"
          className="atelier-section-label block mb-1"
        >
          Product name
        </label>
        <input aria-label=". Dozen Sweet Corn"
          id="atelier-name"
          type="text"
          value={name}
          onChange={(e) => onNameChange(e.target.value)}
          placeholder="e.g. Dozen Sweet Corn"
          className="atelier-input atelier-input--display"
          autoComplete="off"
        />
      </div>

      <div className="mt-5">
        <label
          htmlFor="atelier-desc"
          className="atelier-section-label block mb-1"
        >
          Description
        </label>
        <textarea aria-label="A Note From The Field — Origin, Variety, Picking Notes…"
          id="atelier-desc"
          value={description}
          onChange={(e) => onDescriptionChange(e.target.value)}
          placeholder="A note from the field — origin, variety, picking notes…"
          rows={2}
          className="atelier-input resize-none"
          style={{ minHeight: 56 }}
        />
      </div>
    </section>
  );
}

function CommerceSection({
  price,
  type,
  showBrandPicker,
  brands,
  brandId,
  lockedBrandName,
  onPriceChange,
  onBrandChange,
  onTypeChange,
}: {
  price: string;
  type: ProductFormValues["type"];
  showBrandPicker: boolean;
  brands: { id: string; name: string }[];
  brandId: string;
  lockedBrandName: string;
  onPriceChange: (v: string) => void;
  onBrandChange: (v: string) => void;
  onTypeChange: (v: ProductFormValues["type"]) => void;
}) {
  return (
    <section>
      <div className="atelier-section-num mb-4">03 · Commerce</div>

      <div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
        <div>
          <label
            htmlFor="atelier-price"
            className="atelier-section-label block mb-1"
          >
            Price
          </label>
          <div className="relative">
            <span className="atelier-price-sigil">$</span>
            <input aria-label="0.00"
              id="atelier-price"
              type="number"
              step="0.01"
              min="0"
              value={price}
              onChange={(e) => onPriceChange(e.target.value)}
              placeholder="0.00"
              className="atelier-price"
            />
          </div>
        </div>

        {showBrandPicker ? (
          <BrandPicker
            brands={brands}
            brandId={brandId}
            onBrandChange={onBrandChange}
          />
        ) : (
          <LockedBrandDisplay lockedBrandName={lockedBrandName} />
        )}
      </div>

      <div className="mt-6">
        <span className="atelier-section-label block mb-2">Type</span>
        <TypeSelector type={type} onTypeChange={onTypeChange} />
      </div>
    </section>
  );
}

function BrandPicker({
  brands,
  brandId,
  onBrandChange,
}: {
  brands: { id: string; name: string }[];
  brandId: string;
  onBrandChange: (v: string) => void;
}) {
  return (
    <div>
      <label
        htmlFor="atelier-brand"
        className="atelier-section-label block mb-1"
      >
        Brand
      </label>
      <select aria-label="Atelier Brand"
        id="atelier-brand"
        value={brandId}
        onChange={(e) => onBrandChange(e.target.value)}
        className="atelier-select"
      >
        {brands.length === 0 && <option value="">Loading brands…</option>}
        {brands.length > 0 && <option value="">Select a brand…</option>}
        {brands.map((b) => (
          <option key={b.id} value={b.id}>
            {b.name}
          </option>
        ))}
      </select>
      <p className="atelier-hint">
        You administer multiple brands — choose the one this product belongs to.
      </p>
    </div>
  );
}

function LockedBrandDisplay({ lockedBrandName }: { lockedBrandName: string }) {
  return (
    <div>
      <span className="atelier-section-label block mb-1">Brand</span>
      <div className="py-2.5 border-b border-stone-300/40">
        <span className="font-[family-name:var(--font-fraunces)] text-[15px] text-stone-700">
          {lockedBrandName || "—"}
        </span>
      </div>
    </div>
  );
}

function TypeSelector({
  type,
  onTypeChange,
}: {
  type: ProductFormValues["type"];
  onTypeChange: (v: ProductFormValues["type"]) => void;
}) {
  return (
    <div className="grid grid-cols-3 gap-2.5">
      {TYPE_OPTIONS.map((opt) => (
        <button
          key={opt.value}
          type="button"
          onClick={() => onTypeChange(opt.value)}
          className={[
            "atelier-type-card",
            type === opt.value ? "is-selected" : "",
          ].join(" ")}
          aria-pressed={type === opt.value}
        >
          <div className="flex items-center justify-between w-full">
            <span className="atelier-type-icon">{opt.icon}</span>
            <svg
              className="atelier-type-check h-3.5 w-3.5"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              strokeWidth={3}
            >
              <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
            </svg>
          </div>
          <div>
            <div className="atelier-type-name">{opt.label}</div>
            <div
              className={[
                "text-[10px] font-[family-name:var(--font-fragment-mono)] uppercase tracking-wider mt-0.5",
                type === opt.value ? "text-white/60" : "text-stone-500",
              ].join(" ")}
            >
              {opt.italic}
            </div>
          </div>
        </button>
      ))}
    </div>
  );
}

function SettingsSection({
  active,
  isTaxable,
  availableFrom,
  availableUntil,
  onToggleActive,
  onToggleTaxable,
  onAvailableFromChange,
  onAvailableUntilChange,
  onClearAvailability,
}: {
  active: boolean;
  isTaxable: boolean;
  availableFrom: string;
  availableUntil: string;
  onToggleActive: () => void;
  onToggleTaxable: () => void;
  onAvailableFromChange: (v: string) => void;
  onAvailableUntilChange: (v: string) => void;
  onClearAvailability: () => void;
}) {
  return (
    <section>
      <div className="atelier-section-num mb-4">04 · Settings</div>
      <div className="flex flex-wrap items-center gap-6 sm:gap-10">
        <button
          type="button"
          onClick={onToggleActive}
          className={["atelier-toggle", active ? "is-on" : ""].join(" ")}
          aria-pressed={active}
        >
          <span className="atelier-toggle-track">
            <span className="atelier-toggle-thumb" />
          </span>
          <span className="atelier-toggle-label">Active</span>
        </button>

        <button
          type="button"
          onClick={onToggleTaxable}
          className={["atelier-toggle is-gold", isTaxable ? "is-on" : ""].join(" ")}
          aria-pressed={isTaxable}
        >
          <span className="atelier-toggle-track">
            <span className="atelier-toggle-thumb" />
          </span>
          <span className="atelier-toggle-label">Taxable</span>
        </button>

        <p className="atelier-hint flex-1 min-w-[200px]">
          Active products appear in the storefront. Taxable items add sales tax at checkout.
        </p>
      </div>

      {/* Seasonal Availability */}
      <div className="mt-6 pt-6 border-t border-stone-200/40">
        <span className="atelier-section-label block mb-3">Seasonal Availability</span>
        <p className="atelier-hint mb-4">Set when this product is available (e.g., mid-July through mid-September)</p>
        <div className="grid grid-cols-2 gap-4">
          <div>
            <label htmlFor="atelier-available-from" className="block text-[11px] font-mono uppercase tracking-wider text-stone-500 mb-1.5">Start Date</label>
            <input aria-label="Atelier Available From"
              id="atelier-available-from"
              type="date"
              value={availableFrom}
              onChange={(e) => onAvailableFromChange(e.target.value)}
              className="atelier-input"
            />
          </div>
          <div>
            <label htmlFor="atelier-available-until" className="block text-[11px] font-mono uppercase tracking-wider text-stone-500 mb-1.5">End Date</label>
            <input aria-label="Atelier Available Until"
              id="atelier-available-until"
              type="date"
              value={availableUntil}
              onChange={(e) => onAvailableUntilChange(e.target.value)}
              className="atelier-input"
            />
          </div>
        </div>
        {(availableFrom || availableUntil) && (
          <button
            type="button"
            onClick={onClearAvailability}
            className="mt-2 text-[11px] font-mono uppercase tracking-wider text-stone-400 hover:text-stone-600"
          >
            Clear dates
          </button>
        )}
      </div>
    </section>
  );
}

function FormFooter({
  state,
  mode,
  onClose,
  onSubmit,
}: {
  state: State;
  mode: "add" | "edit";
  onClose: () => void;
  onSubmit: (e: React.FormEvent) => void;
}) {
  return (
    <div className="relative shrink-0 px-6 sm:px-10 pt-4 pb-6 sm:pb-7 border-t border-[var(--admin-border)] bg-[var(--admin-bg)]/80 backdrop-blur-sm">
      <div className="flex items-center justify-between gap-4">
        <button
          type="button"
          onClick={onClose}
          className="atelier-discard"
        >
          discard changes
        </button>

        <div className="flex items-center gap-3">
          {/* readiness indicator */}
          <div className="hidden sm:flex items-center gap-2 text-[11px] font-mono uppercase tracking-wider text-stone-500">
            <span
              className={[
                "h-1.5 w-1.5 rounded-full",
                state.name.trim() && state.price
                  ? "bg-[var(--admin-primary)]"
                  : "bg-stone-300",
              ].join(" ")}
              style={state.name.trim() && state.price ? { boxShadow: "0 0 0 3px var(--admin-primary-soft)" } : undefined}
            />
            {state.name.trim() && state.price ? "Ready" : "Required fields pending"}
          </div>

          <button
            type="submit"
            form="atelier-product-form"
            onClick={onSubmit}
            disabled={state.saving || state.uploading || !state.name.trim() || !state.price}
            className="atelier-cta"
          >
            <span className="atelier-cta-shimmer" />
            {state.saving ? (
              <>
                <span className="h-3.5 w-3.5 rounded-full border-2 border-white/40 border-t-white animate-spin" />
                {mode === "add" ? "Composing…" : "Saving…"}
              </>
            ) : (
              <>
                {mode === "add" ? "Add to catalog" : "Save changes"}
                <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.2}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3" />
                </svg>
              </>
            )}
          </button>
        </div>
      </div>
    </div>
  );
}
