// components/forms/SettingsSubmit.tsx
"use client";

import { useEffect, useMemo, useState } from "react";
import { useForm, useFieldArray, type UseFormRegister } from "react-hook-form";
import { useRouter } from "next/navigation";

/**
 * From-scratch CO₂ Galvo form that follows the data sheet.
 * - Prefill works via reset() with raw IDs.
 * - Submits via /app/api/settings (this file does not assume any old helpers).
 * - Lens options belong to Rig & Optics (not a separate "Lens Options" section).
 */

type Target = "settings_co2gal";

type Opt = { id: string; label: string };
type Me = { id: string; username?: string; email?: string };

const API = (process.env.NEXT_PUBLIC_API_BASE_URL || "").replace(/\/$/, "");

type EditInitialValues = {
  submission_id: string | number;

  setting_title?: string;
  setting_notes?: string;

  photo?: string | null;
  screen?: string | null;

  // Material
  mat?: string | null;
  mat_coat?: string | null;
  mat_color?: string | null;
  mat_opacity?: string | null;
  mat_thickness?: number | null;

  // Rig & Optics
  laser_soft?: string | null;
  source?: string | null; // submission_id
  lens?: string | null;
  focus?: number | null;
  // CO2 Galvo triplet (Rig & Optics)
  lens_conf?: string | null;
  lens_apt?: string | null;
  lens_exp?: string | null;

  repeat_all?: number | null;

  // Repeaters
  fill_settings?: any[] | null;
  line_settings?: any[] | null;
  raster_settings?: any[] | null;
};

type BaseProps = { mode?: "create" | "edit"; submissionId?: string | number; initialValues?: EditInitialValues | null };
export default function SettingsSubmit({ mode = "create", submissionId, initialValues }: BaseProps) {
  const router = useRouter();
  const isEdit = mode === "edit";

  const [me, setMe] = useState<Me | null>(null);
  const [submitErr, setSubmitErr] = useState<string | null>(null);

  useEffect(() => {
    let alive = true;
    fetch(`/api/me`, { cache: "no-store", credentials: "include" })
    .then((r) => (r.ok ? r.json() : null))
    .then((j) => alive && setMe(j || null))
    .catch(() => alive && setMe(null));
    return () => {
      alive = false;
    };
  }, []);

  // Options loaders (raw Directus reads)
  function useOptions(path: string, includeId?: string | null) {
    const [opts, setOpts] = useState<Opt[]>([]);
    useEffect(() => {
      let live = true;

      (async () => {
        let url = "";
        let map = (rows: any[]) => rows.map((r) => ({ id: String(r.id ?? r.submission_id), label: String(r.name ?? r.model ?? r.opacity ?? r.id) }));

        if (path === "material") url = `${API}/items/material?fields=id,name&limit=1000&sort=name`;
        else if (path === "material_coating") url = `${API}/items/material_coating?fields=id,name&limit=1000&sort=name`;
        else if (path === "material_color") url = `${API}/items/material_color?fields=id,name&limit=1000&sort=name`;
        else if (path === "material_opacity") {
          url = `${API}/items/material_opacity?fields=id,opacity&limit=1000&sort=opacity`;
          map = (rows) => rows.map((r) => ({ id: String(r.id), label: String(r.opacity ?? r.id) }));
        } else if (path === "laser_software") {
          url = `${API}/items/laser_software?fields=id,name&limit=1000&sort=name`;
        } else if (path === "laser_source_co2_galvo") {
          url = `${API}/items/laser_source?fields=submission_id,make,model,nm&limit=2000&sort=make,model`;
          // Explicitly reference the global Number to avoid the local <Number/> component shadowing it.
          type Row = { submission_id?: string | number; make?: string; model?: string; nm?: string | number | null };
          const toNum = (v: unknown): number | null => {
            if (typeof v === "number") return globalThis.Number.isFinite(v) ? v : null;
            if (typeof v === "string") {
              const m = v.match(/-?\d+(\.\d+)?/);
              const n = m ? globalThis.Number(m[0]) : NaN;
              return globalThis.Number.isFinite(n) ? n : null;
            }
            return null;
          };
          map = (rows: Row[]) =>
          rows
          .filter((r) => {
            const nmVal = toNum(r.nm);
            return nmVal !== null && nmVal >= 10000 && nmVal <= 11000;
          })
          .map((r) => ({
            id: String(r.submission_id ?? ""),
                       label: [r.make, r.model].filter(Boolean).join(" ") || String(r.submission_id ?? ""),
          }));
        } else if (path === "laser_scan_lens") {
          url = `${API}/items/laser_scan_lens?fields=id,field_size,focal_length&limit=1000`;
          map = (rows) =>
          rows
          .slice()
          .sort((a, b) => (parseFloat(a.focal_length ?? "99999") || 99999) - (parseFloat(b.focal_length ?? "99999") || 99999))
          .map((r) => {
            const fs = r.field_size ? `${r.field_size} mm` : "";
            const fl = r.focal_length ? `${r.focal_length} mm` : "";
            const label = [fs, fl].filter(Boolean).join(" — ") || String(r.id);
            return { id: String(r.id), label };
          });
        } else if (path === "laser_scan_lens_config") {
          url = `${API}/items/laser_scan_lens_config?fields=id,name&limit=1000&sort=name`;
        } else if (path === "laser_scan_lens_apt") {
          url = `${API}/items/laser_scan_lens_apt?fields=id,name&limit=1000&sort=name`;
        } else if (path === "laser_scan_lens_exp") {
          url = `${API}/items/laser_scan_lens_exp?fields=id,name&limit=1000&sort=name`;
        } else {
          setOpts([]);
          return;
        }

        const res = await fetch(url, { cache: "no-store", credentials: "include" });
        const j = await res.json().catch(() => ({}));
        const rows = Array.isArray(j?.data) ? j.data : [];
        let list = map(rows);

        if (includeId && !list.some((o) => String(o.id) === String(includeId))) {
          list = [{ id: String(includeId), label: "(current selection)" }, ...list];
        }
        if (live) setOpts(list);
      })().catch(() => live && setOpts([]));

        return () => {
          live = false;
        };
    }, [path, includeId]);

    return { opts };
  }

  // Enumerations
  const FILL_TYPES: Opt[] = [
    { id: "uni", label: "UniDirectional" },
    { id: "bi", label: "BiDirectional" },
    { id: "offset", label: "Offset Fill" },
  ];
  const RASTER_TYPES = FILL_TYPES;
  const RASTER_DITHER: Opt[] = [
    "threshold",
    "ordered",
    "atkinson",
    "dither",
    "stucki",
    "jarvis",
    "newsprint",
    "halftone",
    "sketch",
    "grayscale",
  ].map((x) => ({ id: x, label: x[0].toUpperCase() + x.slice(1) }));

  // react-hook-form
  const {
    register,
    handleSubmit,
    control,
    reset,
    formState: { isSubmitting },
  } = useForm<any>({
    defaultValues: {
      setting_title: "",
      setting_notes: "",
      // Material
      mat: "",
      mat_coat: "",
      mat_color: "",
      mat_opacity: "",
      mat_thickness: "",
      // Rig & Optics
      laser_soft: "",
      source: "",
      lens: "",
      focus: "",
      lens_conf: "",
      lens_apt: "",
      lens_exp: "",
      repeat_all: "",
      // Repeaters
      fill_settings: [],
      line_settings: [],
      raster_settings: [],
    },
  });

  // Repeaters
  const fills = useFieldArray({ control, name: "fill_settings" });
  const lines = useFieldArray({ control, name: "line_settings" });
  const rasters = useFieldArray({ control, name: "raster_settings" });

  // Prefill (edit)
  useEffect(() => {
    if (!isEdit || !initialValues) return;
    reset({
      setting_title: initialValues.setting_title ?? "",
      setting_notes: initialValues.setting_notes ?? "",
      // Material
      mat: initialValues.mat ?? "",
      mat_coat: initialValues.mat_coat ?? "",
      mat_color: initialValues.mat_color ?? "",
      mat_opacity: initialValues.mat_opacity ?? "",
      mat_thickness: initialValues.mat_thickness ?? "",
      // Rig & Optics
      laser_soft: initialValues.laser_soft ?? "",
      source: initialValues.source ?? "",
      lens: initialValues.lens ?? "",
      focus: initialValues.focus ?? "",
      lens_conf: initialValues.lens_conf ?? "",
      lens_apt: initialValues.lens_apt ?? "",
      lens_exp: initialValues.lens_exp ?? "",
      repeat_all: initialValues.repeat_all ?? "",
      // Repeaters
      fill_settings: initialValues.fill_settings ?? [],
      line_settings: initialValues.line_settings ?? [],
      raster_settings: initialValues.raster_settings ?? [],
    });
  }, [isEdit, initialValues, reset]);

  // Option lists (include current IDs to guarantee a visible option)
  const mats = useOptions("material", initialValues?.mat ?? null);
  const coats = useOptions("material_coating", initialValues?.mat_coat ?? null);
  const colors = useOptions("material_color", initialValues?.mat_color ?? null);
  const opacs = useOptions("material_opacity", initialValues?.mat_opacity ?? null);
  const soft = useOptions("laser_software", initialValues?.laser_soft ?? null);
  const srcs = useOptions("laser_source_co2_galvo", initialValues?.source ?? null);
  const lens = useOptions("laser_scan_lens", initialValues?.lens ?? null);
  const conf = useOptions("laser_scan_lens_config", initialValues?.lens_conf ?? null);
  const apt = useOptions("laser_scan_lens_apt", initialValues?.lens_apt ?? null);
  const exp = useOptions("laser_scan_lens_exp", initialValues?.lens_exp ?? null);

  // Image files
  const [photoFile, setPhotoFile] = useState<File | null>(null);
  const [screenFile, setScreenFile] = useState<File | null>(null);
  const onPick = (setter: (f: File | null) => void) => (e: React.ChangeEvent<HTMLInputElement>) => setter(e.target.files?.[0] ?? null);

  const onSubmit = async (values: any) => {
    setSubmitErr(null);
    const payload: any = {
      target: "settings_co2gal" as Target,
      ...(isEdit ? { mode: "edit" as const, submission_id: submissionId } : {}),
      setting_title: values.setting_title,
      setting_notes: values.setting_notes || "",
      // Material
      mat: values.mat || null,
      mat_coat: values.mat_coat || null,
      mat_color: values.mat_color || null,
      mat_opacity: values.mat_opacity || null,
      mat_thickness: values.mat_thickness === "" ? null : Number(values.mat_thickness),
      // Rig & Optics
      laser_soft: values.laser_soft || null,
      source: values.source || null,
      lens: values.lens || null,
      focus: values.focus === "" ? null : Number(values.focus),
      lens_conf: values.lens_conf || null,
      lens_apt: values.lens_apt || null,
      lens_exp: values.lens_exp || null,
      repeat_all: values.repeat_all === "" ? null : Number(values.repeat_all),
      // Repeaters (raw pass-through; api will normalize nums/bools)
      fill_settings: values.fill_settings || [],
      line_settings: values.line_settings || [],
      raster_settings: values.raster_settings || [],
      // If editing with existing asset IDs, the API will accept them
      ...(initialValues?.photo ? { photo: initialValues.photo } : {}),
      ...(initialValues?.screen ? { screen: initialValues.screen } : {}),
    };

    const form = new FormData();
    form.set("payload", JSON.stringify(payload));
    if (photoFile) form.set("photo", photoFile, photoFile.name || "photo");
    if (screenFile) form.set("screen", screenFile, screenFile.name || "screen");

    const res = await fetch("/api/settings", { method: "POST", body: form, credentials: "include" });
    const j = await res.json().catch(() => ({}));
    if (!res.ok) {
      setSubmitErr(j?.error || `Submit failed (${res.status})`);
      return;
    }

    if (isEdit) {
      router.back();
    } else {
      reset();
      setPhotoFile(null);
      setScreenFile(null);
      router.push(`/submit/settings/success?id=${encodeURIComponent(String(j?.id ?? ""))}`);
    }
  };

  return (
    <div className="space-y-5">
    <header className="space-y-1">
    <h1 className="text-xl font-semibold">{isEdit ? "Edit CO₂ Galvo Setting" : "Submit CO₂ Galvo Setting"}</h1>
    {me ? <p className="text-sm text-muted-foreground">Submitting as {me.username || me.email}</p> : null}
    {submitErr ? <div className="border border-red-500 bg-red-50 text-red-700 rounded px-3 py-2 text-sm">{submitErr}</div> : null}
    </header>

    <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
    {/* Info */}
    <section className="space-y-3">
    <h2 className="text-lg font-semibold">Info</h2>
    <div className="grid gap-3">
    <div>
    <label className="block text-sm mb-1">Title *</label>
    <input className="w-full border rounded px-2 py-1" {...register("setting_title", { required: true })} />
    </div>
    <div>
    <label className="block text-sm mb-1">Notes</label>
    <textarea rows={4} className="w-full border rounded px-2 py-1" {...register("setting_notes")} />
    </div>
    </div>
    </section>

    {/* Images */}
    <section className="space-y-3">
    <h2 className="text-lg font-semibold">Images</h2>
    <div className="grid md:grid-cols-2 gap-3">
    <div>
    <label className="block text-sm mb-1">Result Photo {isEdit || initialValues?.photo ? null : <span className="text-red-600">*</span>}</label>
    <input type="file" accept="image/*" onChange={onPick(setPhotoFile)} />
    </div>
    <div>
    <label className="block text-sm mb-1">Settings Screenshot (optional)</label>
    <input type="file" accept="image/*" onChange={onPick(setScreenFile)} />
    </div>
    </div>
    </section>

    {/* Material */}
    <section className="space-y-3">
    <h2 className="text-lg font-semibold">Material</h2>
    <div className="grid md:grid-cols-2 gap-3">
    <Select label="Material *" {...{ name: "mat", register, options: mats.opts, required: true }} />
    <Select label="Coating *" {...{ name: "mat_coat", register, options: coats.opts, required: true }} />
    <Select label="Color *" {...{ name: "mat_color", register, options: colors.opts, required: true }} />
    <Select label="Opacity *" {...{ name: "mat_opacity", register, options: opacs.opts, required: true }} />
    <Number label="Material Thickness (mm)" name="mat_thickness" register={register} step="0.01" />
    </div>
    </section>

    {/* Rig & Optics (includes lens_conf/apt/exp) */}
    <section className="space-y-3">
    <h2 className="text-lg font-semibold">Rig & Optics</h2>
    <div className="grid md:grid-cols-2 gap-3">
    <Select label="Software *" {...{ name: "laser_soft", register, options: soft.opts, required: true }} />
    <Select label="Laser Source *" {...{ name: "source", register, options: srcs.opts, required: true }} />
    <Select label="Scan Lens *" {...{ name: "lens", register, options: lens.opts, required: true }} />
    <Number label="Focus (mm) *" name="focus" register={register} step="1" />
    <Number label="Repeat All" name="repeat_all" register={register} step="1" />
    </div>
    <div className="grid md:grid-cols-3 gap-3">
    <Select label="Lens Configuration *" {...{ name: "lens_conf", register, options: conf.opts, required: true }} />
    <Select label="Scan Head Aperture *" {...{ name: "lens_apt", register, options: apt.opts, required: true }} />
    <Select label="Beam Expander *" {...{ name: "lens_exp", register, options: exp.opts, required: true }} />
    </div>
    </section>

    {/* Process Settings */}
    <section className="space-y-4">
    <h2 className="text-lg font-semibold">Process Settings</h2>

    {/* Fill */}
    <Repeater
    title="Fill"
    fields={fills.fields}
    onAdd={() => fills.append({ type: "uni" })}
    onRemove={(i) => fills.remove(i)}
    render={(i) => (
      <div className="grid md:grid-cols-4 gap-2">
      <Text label="Name" name={`fill_settings.${i}.name`} register={register} />
      <Select label="Type" name={`fill_settings.${i}.type`} register={register} options={FILL_TYPES} />
      <Number label="Frequency (kHz)" name={`fill_settings.${i}.frequency`} register={register} step="0.1" />
      <Number label="Pulse (ns)" name={`fill_settings.${i}.pulse`} register={register} step="0.1" />
      <Number label="Power (%)" name={`fill_settings.${i}.power`} register={register} step="0.1" />
      <Number label="Speed (mm/s)" name={`fill_settings.${i}.speed`} register={register} step="0.1" />
      <Number label="Interval (mm)" name={`fill_settings.${i}.interval`} register={register} step="0.001" />
      <Number label="Pass" name={`fill_settings.${i}.pass`} register={register} step="1" />
      <Number label="Angle (°)" name={`fill_settings.${i}.angle`} register={register} step="1" />
      <Number label="Increment" name={`fill_settings.${i}.increment`} register={register} step="0.001" />
      <Check label="Auto" name={`fill_settings.${i}.auto`} register={register} />
      <Check label="Cross" name={`fill_settings.${i}.cross`} register={register} />
      <Check label="Flood" name={`fill_settings.${i}.flood`} register={register} />
      <Check label="Air" name={`fill_settings.${i}.air`} register={register} />
      </div>
    )}
    />

    {/* Line */}
    <Repeater
    title="Line"
    fields={lines.fields}
    onAdd={() => lines.append({})}
    onRemove={(i) => lines.remove(i)}
    render={(i) => (
      <div className="grid md:grid-cols-4 gap-2">
      <Text label="Name" name={`line_settings.${i}.name`} register={register} />
      <Number label="Frequency (kHz)" name={`line_settings.${i}.frequency`} register={register} step="0.1" />
      <Number label="Pulse (ns)" name={`line_settings.${i}.pulse`} register={register} step="0.1" />
      <Number label="Power (%)" name={`line_settings.${i}.power`} register={register} step="0.1" />
      <Number label="Speed (mm/s)" name={`line_settings.${i}.speed`} register={register} step="0.1" />
      <Check label="Perf" name={`line_settings.${i}.perf`} register={register} />
      <Check label="Cut" name={`line_settings.${i}.cut`} register={register} />
      <Check label="Skip" name={`line_settings.${i}.skip`} register={register} />
      <Number label="Pass" name={`line_settings.${i}.pass`} register={register} step="1" />
      <Number label="Step" name={`line_settings.${i}.step`} register={register} step="0.001" />
      <Number label="Size" name={`line_settings.${i}.size`} register={register} step="0.001" />
      <Check label="Wobble" name={`line_settings.${i}.wobble`} register={register} />
      <Check label="Air" name={`line_settings.${i}.air`} register={register} />
      </div>
    )}
    />

    {/* Raster */}
    <Repeater
    title="Raster"
    fields={rasters.fields}
    onAdd={() => rasters.append({ type: "uni", dither: "threshold" })}
    onRemove={(i) => rasters.remove(i)}
    render={(i) => (
      <div className="grid md:grid-cols-4 gap-2">
      <Text label="Name" name={`raster_settings.${i}.name`} register={register} />
      <Number label="Frequency (kHz)" name={`raster_settings.${i}.frequency`} register={register} step="0.1" />
      <Number label="Pulse (ns)" name={`raster_settings.${i}.pulse`} register={register} step="0.1" />
      <Select label="Type" name={`raster_settings.${i}.type`} register={register} options={RASTER_TYPES} />
      <Select label="Dither" name={`raster_settings.${i}.dither`} register={register} options={RASTER_DITHER} />
      <Number label="Power (%)" name={`raster_settings.${i}.power`} register={register} step="0.1" />
      <Number label="Speed (mm/s)" name={`raster_settings.${i}.speed`} register={register} step="0.1" />
      <Number label="Halftone Cell" name={`raster_settings.${i}.halftone_cell`} register={register} step="1" />
      <Number label="Halftone Angle" name={`raster_settings.${i}.halftone_angle`} register={register} step="1" />
      <Number label="Interval (mm)" name={`raster_settings.${i}.interval`} register={register} step="0.001" />
      <Number label="Dot" name={`raster_settings.${i}.dot`} register={register} step="0.1" />
      <Number label="Pass" name={`raster_settings.${i}.pass`} register={register} step="1" />
      <Check label="Cross" name={`raster_settings.${i}.cross`} register={register} />
      <Check label="Inversion" name={`raster_settings.${i}.inversion`} register={register} />
      <Check label="Air" name={`raster_settings.${i}.air`} register={register} />
      </div>
    )}
    />
    </section>

    <button disabled={isSubmitting} className="px-3 py-2 border rounded bg-accent text-background disabled:opacity-50">
    {isSubmitting ? "Submitting…" : isEdit ? "Save Changes" : "Submit Settings"}
    </button>
    </form>
    </div>
  );
}

/* Small UI */
function Select({
  label,
  name,
  register,
  options,
  required,
}: { label: string; name: string; register: UseFormRegister<any>; options: Opt[]; required?: boolean }) {
  return (
    <div>
    <label className="block text-sm mb-1">
    {label} {required ? <span className="text-red-600">*</span> : null}
    </label>
    <select className="w-full border rounded px-2 py-1" {...register(name, { required })}>
    <option value="">—</option>
    {options.map((o) => (
      <option key={o.id} value={o.id}>
      {o.label}
      </option>
    ))}
    </select>
    </div>
  );
}
function Number({ label, name, register, step }: any) {
  return (
    <div>
    <label className="block text-sm mb-1">{label}</label>
    <input type="number" step={step ?? "1"} className="w-full border rounded px-2 py-1" {...register(name)} />
    </div>
  );
}
function Text({ label, name, register }: any) {
  return (
    <div>
    <label className="block text-sm mb-1">{label}</label>
    <input className="w-full border rounded px-2 py-1" {...register(name)} />
    </div>
  );
}
function Check({ label, name, register }: any) {
  return (
    <label className="flex items-center gap-2 text-sm">
    <input type="checkbox" {...register(name)} /> {label}
    </label>
  );
}
function Repeater({ title, fields, onAdd, onRemove, render }: any) {
  return (
    <fieldset className="border rounded p-3 space-y-2">
    <div className="flex items-center justify-between">
    <legend className="font-semibold">{title}</legend>
    <button type="button" className="px-2 py-1 border rounded" onClick={onAdd}>
    + Add
    </button>
    </div>
    {fields.map((_: any, i: number) => (
      <div key={i} className="space-y-2">
      {render(i)}
      <button type="button" className="px-2 py-1 border rounded" onClick={() => onRemove(i)}>
      Remove
      </button>
      </div>
    ))}
    </fieldset>
  );
}
