"use client";

import { useRouter } from "next/navigation";
import { useId, useState, useTransition } from "react";
import { Button, Card } from "@/components/ui";
import { Field, inputClass } from "@/components/ui/form";
import { createModuleAction, deleteModuleAction, setModuleActiveAction, updateModuleAction } from "@/lib/actions/modules";
import type { FieldDef } from "@/lib/blocks/defs";
import { ModuleFields } from "./module-fields";
import { FieldList, blankField, fromDef, toDef, type EField } from "./field-editor";

export interface ModuleBuilderInitial { key: string; label: string; plural: string; description: string; titleLabel: string; supportsCategories: boolean; supportsFeaturedImage: boolean; fields: FieldDef[]; active: boolean; entries: number }

const slugKey = (s: string) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^[^a-z]+/, "").replace(/-+$/, "").slice(0, 30);

/** Super-admin builder: what the module is called, which fields an entry has, and whether it offers categories and a featured image. */
export function ModuleBuilder({ mode, initial, base }: { mode: "create" | "edit"; initial: ModuleBuilderInitial; base: string }) {
  const uid = useId();
  const router = useRouter();
  const [v, setV] = useState({ key: initial.key, label: initial.label, plural: initial.plural, description: initial.description, titleLabel: initial.titleLabel, supportsCategories: initial.supportsCategories, supportsFeaturedImage: initial.supportsFeaturedImage });
  const [keyTouched, setKeyTouched] = useState(mode === "edit");
  const [fields, setFields] = useState<EField[]>(initial.fields.length ? initial.fields.map(fromDef) : [blankField()]);
  const [msg, setMsg] = useState<{ ok: boolean; text: string } | null>(null);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [armed, setArmed] = useState(false);
  const [pending, start] = useTransition();
  const set = (p: Partial<typeof v>) => setV((x) => ({ ...x, ...p }));
  const payload = () => ({ ...v, fields: mode === "edit" ? initial.fields : fields.map(toDef) });
  const done = (r: { ok: boolean; message?: string; error?: string; fieldErrors?: Record<string, string> }, after?: () => void) => {
    setErrors(r.fieldErrors ?? {}); setMsg({ ok: r.ok, text: r.ok ? (r.message ?? "Saved") : (r.error ?? "Failed") });
    if (r.ok) after?.();
  };
  const save = () => start(async () => {
    if (mode === "create") { const r = await createModuleAction(payload()); done(r, () => router.push(`${base}/${r.ok ? r.data?.key : ""}`)); }
    else { const r = await updateModuleAction(initial.key, { ...payload(), key: undefined }); done(r, () => router.refresh()); }
  });
  const errList = Object.entries(errors);
  return (
    <div className="space-y-4">
      <Card className="space-y-3 p-4">
        <h2 className="text-sm font-semibold">Module</h2>
        <div className="grid gap-3 sm:grid-cols-2">
          <Field id={`${uid}-label`} label="Name (singular)" help="For example: Job offer"><input id={`${uid}-label`} className={inputClass} maxLength={60} value={v.label} onChange={(e) => set({ label: e.target.value, ...(mode === "create" && !keyTouched ? { key: slugKey(e.target.value) } : {}) })} /></Field>
          <Field id={`${uid}-plural`} label="Name (plural)" help="Shown in menus. For example: Job offers"><input id={`${uid}-plural`} className={inputClass} maxLength={60} value={v.plural} onChange={(e) => set({ plural: e.target.value })} /></Field>
          <Field id={`${uid}-key`} label="Key" help={mode === "create" ? "Used in addresses and can never be changed. Lowercase letters, numbers and hyphens." : "The key cannot be changed."} error={errors.key}><input id={`${uid}-key`} className={inputClass} maxLength={30} value={v.key} disabled={mode === "edit"} onChange={(e) => { setKeyTouched(true); set({ key: e.target.value }); }} /></Field>
          <Field id={`${uid}-title`} label="What the entry title is called" help="For example: Role"><input id={`${uid}-title`} className={inputClass} maxLength={60} value={v.titleLabel} onChange={(e) => set({ titleLabel: e.target.value })} /></Field>
          <Field id={`${uid}-desc`} label="Description" className="sm:col-span-2"><input id={`${uid}-desc`} className={inputClass} maxLength={200} value={v.description} onChange={(e) => set({ description: e.target.value })} /></Field>
        </div>
        <div className="flex flex-wrap gap-6 text-sm">
          <label className="flex items-center gap-2"><input type="checkbox" checked={v.supportsCategories} onChange={(e) => set({ supportsCategories: e.target.checked })} />Entries can be placed in categories</label>
          <label className="flex items-center gap-2"><input type="checkbox" checked={v.supportsFeaturedImage} onChange={(e) => set({ supportsFeaturedImage: e.target.checked })} />Entries have a featured image</label>
        </div>
      </Card>
      {mode === "edit" ? <ModuleFields moduleKey={initial.key} fields={initial.fields} /> : (
      <Card className="space-y-3 p-4">
        <h2 className="text-sm font-semibold">Fields</h2>
        <p className="text-xs text-muted-foreground">Every entry also has a title, URL name, status, SEO fields and an optional category and image. Add the fields specific to this module here. Removing a field hides it; values already saved for it are dropped the next time an entry is saved.</p>
        <FieldList fields={fields} idp={`${uid}-f`} onChange={setFields} />
      </Card>
      )}
      <p role="status" aria-live="polite" className={msg ? (msg.ok ? "text-sm text-success" : "text-sm text-danger") : "sr-only"}>{msg?.text}</p>
      {errList.length ? <ul role="alert" className="list-disc pl-5 text-xs text-danger">{errList.slice(0, 8).map(([k, m]) => <li key={k}>{k.replace(/^fields\.(\d+)/, (_, n) => `Field ${Number(n) + 1}`)}: {m}</li>)}</ul> : null}
      <div className="flex flex-wrap gap-2">
        <Button disabled={pending} onClick={save}>{pending ? "Saving…" : mode === "create" ? "Create module" : "Save details"}</Button>
        {mode === "edit" ? (
          <>
            <Button variant="secondary" disabled={pending} onClick={() => start(async () => { done(await setModuleActiveAction(initial.key, !initial.active), () => router.refresh()); })}>{initial.active ? "Deactivate" : "Activate"}</Button>
            {armed ? (<><Button variant="danger" disabled={pending} onClick={() => start(async () => { const r = await deleteModuleAction(initial.key); done(r, () => router.push(base)); setArmed(false); })}>Confirm delete</Button><Button variant="ghost" onClick={() => setArmed(false)}>Cancel</Button></>) : <Button variant="ghost" onClick={() => setArmed(true)} aria-describedby={`${uid}-del`}>Delete</Button>}
            <span id={`${uid}-del`} className="self-center text-xs text-muted-foreground">{initial.entries > 0 ? `${initial.entries} entries exist, so it can only be deactivated.` : "Deleting also removes it from every website's licence."}</span>
          </>
        ) : null}
      </div>
    </div>
  );
}
