// Booking Forms (Cards) — list + editor backed by Supabase.
//   • Local edits autosave after a short debounce.
//   • Publish/unpublish, add/remove/move field, and delete save immediately.
//   • A "Start from template" picker seeds new forms with sensible field sets.

const FIELD_TYPES = [
  { id: "short",    label: "Short text",   icon: "type" },
  { id: "long",     label: "Long text",    icon: "align-left" },
  { id: "email",    label: "Email",        icon: "at-sign" },
  { id: "phone",    label: "Phone",        icon: "phone" },
  { id: "number",   label: "Number",       icon: "hash" },
  { id: "dropdown", label: "Dropdown",     icon: "chevron-down" },
  { id: "multi",    label: "Multi-select", icon: "list-checks" },
  { id: "date",     label: "Date",         icon: "calendar" },
  { id: "time",     label: "Time",         icon: "clock" },
  { id: "checkbox", label: "Checkbox",     icon: "check-square" },
  { id: "radio",    label: "Radio",        icon: "circle-dot" },
  { id: "party",    label: "Party size",   icon: "users" },
  { id: "vehicle",  label: "Vehicle type", icon: "car" },
  { id: "service",  label: "Service type", icon: "wrench" },
  { id: "address",  label: "Address",      icon: "map-pin" }
];
function fieldTypeMeta(id) { return FIELD_TYPES.find(t => t.id === id) || FIELD_TYPES[0]; }

const COMMON_FIELDS = {
  name:  { id: "fl_name",  label: "Full name", type: "short", required: true },
  email: { id: "fl_email", label: "Email",     type: "email", required: true },
  phone: { id: "fl_phone", label: "Phone",     type: "phone", required: true }
};

const FORM_TEMPLATES = [
  {
    id: "blank",
    name: "Blank form",
    desc: "Just name, email, phone. Add your own questions.",
    seed: {
      name: "New form",
      public_title: "Book an appointment",
      description: "",
      duration_min: 30,
      buffer_min: 0,
      confirmation_mode: "manual",
      fields: [COMMON_FIELDS.name, COMMON_FIELDS.email, COMMON_FIELDS.phone]
    }
  },
  {
    id: "powersports",
    name: "Powersports maintenance",
    desc: "Vehicle make/model, service type, mileage.",
    seed: {
      name: "Powersports Maintenance",
      public_title: "Schedule Service",
      description: "Tell us about your vehicle and we'll confirm a time within one business day.",
      duration_min: 90,
      buffer_min: 15,
      confirmation_mode: "manual",
      fields: [
        COMMON_FIELDS.name, COMMON_FIELDS.email, COMMON_FIELDS.phone,
        { id: "fl_vehicle", label: "Vehicle type", type: "vehicle", required: true },
        { id: "fl_year",    label: "Year",         type: "number",  required: true },
        { id: "fl_service", label: "Service needed", type: "multi", required: true, options: ["Oil change","Tire service","Annual inspection","Diagnostic","Other"] },
        { id: "fl_notes",   label: "Anything else?", type: "long",  required: false }
      ]
    }
  },
  {
    id: "restaurant",
    name: "Restaurant reservation",
    desc: "Party size, occasion, dietary notes.",
    seed: {
      name: "Dinner Reservation",
      public_title: "Reserve a Table",
      description: "Reservations open 30 days in advance.",
      duration_min: 120,
      buffer_min: 0,
      confirmation_mode: "instant",
      fields: [
        COMMON_FIELDS.name, COMMON_FIELDS.email, COMMON_FIELDS.phone,
        { id: "fl_party",    label: "Party size", type: "party",    required: true },
        { id: "fl_occasion", label: "Occasion",   type: "dropdown", required: false, options: ["—","Birthday","Anniversary","Business","Other"] },
        { id: "fl_diet",     label: "Allergies / dietary notes", type: "long", required: false }
      ]
    }
  },
  {
    id: "dentist",
    name: "Dentist appointment",
    desc: "Reason for visit, insurance, last cleaning.",
    seed: {
      name: "New Patient Intake",
      public_title: "Schedule Your Visit",
      description: "",
      duration_min: 60,
      buffer_min: 15,
      confirmation_mode: "manual",
      fields: [
        COMMON_FIELDS.name, COMMON_FIELDS.email, COMMON_FIELDS.phone,
        { id: "fl_dob",       label: "Date of birth", type: "date", required: true },
        { id: "fl_insurance", label: "Insurance carrier", type: "short", required: true },
        { id: "fl_reason",    label: "Reason for visit", type: "long", required: true }
      ]
    }
  },
  {
    id: "consultation",
    name: "Consultation",
    desc: "Short discovery call to discuss a project.",
    seed: {
      name: "30-min Consultation",
      public_title: "Book a Consultation",
      description: "Free 30-minute call to discuss your project.",
      duration_min: 30,
      buffer_min: 10,
      confirmation_mode: "instant",
      fields: [
        COMMON_FIELDS.name, COMMON_FIELDS.email,
        { id: "fl_company", label: "Company", type: "short", required: false },
        { id: "fl_topic",   label: "Topic",   type: "long",  required: true }
      ]
    }
  }
];

function BookingFormsPage() {
  const auth = useAuth();
  const ws = auth.currentWorkspace;
  const toast = useToast();

  const [forms, setForms] = useState([]);
  const [activeId, setActiveId] = useState(null);
  const [loading, setLoading] = useState(true);
  const [showTemplates, setShowTemplates] = useState(false);
  const [staff, setStaff] = useState([]);

  // Track in-flight saves so we can show a "Saving…" indicator.
  const [saveState, setSaveState] = useState({ saving: false, savedAt: null, error: null });

  const load = useCallback(async () => {
    if (!ws?.id) { setLoading(false); return; }
    setLoading(true);
    const [formsRes, staffRes] = await Promise.all([
      SB.from('forms').select('*').eq('workspace_id', ws.id).is('archived_at', null).order('created_at'),
      SB.from('staff_resources').select('*').eq('workspace_id', ws.id).is('archived_at', null)
    ]);
    setLoading(false);
    if (formsRes.error) { toast.push(formsRes.error.message); return; }
    setForms(formsRes.data || []);
    setStaff(staffRes.data || []);
    setActiveId((prev) => prev && (formsRes.data || []).some(f => f.id === prev) ? prev : (formsRes.data?.[0]?.id || null));
  }, [ws?.id, toast]);

  useEffect(() => { load(); }, [load]);

  const active = forms.find((f) => f.id === activeId) || null;

  // Debounced save. We collect the latest patch keyed by form id; on flush we
  // send a single UPDATE with everything that changed.
  const pendingPatchRef = useRef({});
  const flushTimerRef = useRef(null);

  const flushSaves = useCallback(async () => {
    const pending = pendingPatchRef.current;
    pendingPatchRef.current = {};
    flushTimerRef.current = null;
    const ids = Object.keys(pending);
    if (ids.length === 0) return;
    setSaveState({ saving: true, savedAt: null, error: null });
    for (const id of ids) {
      const res = await SB.from('forms').update(pending[id]).eq('id', id);
      if (res.error) {
        setSaveState({ saving: false, savedAt: null, error: res.error.message });
        toast.push("Couldn't save: " + res.error.message);
        return;
      }
    }
    setSaveState({ saving: false, savedAt: Date.now(), error: null });
  }, [toast]);

  const queueSave = useCallback((id, patch) => {
    pendingPatchRef.current[id] = Object.assign({}, pendingPatchRef.current[id] || {}, patch);
    if (flushTimerRef.current) clearTimeout(flushTimerRef.current);
    flushTimerRef.current = setTimeout(flushSaves, 700);
  }, [flushSaves]);

  // Edit the active form: update local state, queue a save.
  const updateActive = useCallback((patch) => {
    if (!activeId) return;
    setForms(prev => prev.map(f => f.id === activeId ? Object.assign({}, f, patch) : f));
    queueSave(activeId, patch);
  }, [activeId, queueSave]);

  // Field operations save the whole fields array immediately.
  const saveFieldsNow = useCallback(async (nextFields) => {
    if (!active) return;
    setForms(prev => prev.map(f => f.id === activeId ? Object.assign({}, f, { fields: nextFields }) : f));
    pendingPatchRef.current[activeId] = Object.assign({}, pendingPatchRef.current[activeId] || {}, { fields: nextFields });
    if (flushTimerRef.current) { clearTimeout(flushTimerRef.current); flushTimerRef.current = null; }
    await flushSaves();
  }, [active, activeId, flushSaves]);

  const addField = (type) => {
    if (!active) return;
    const meta = fieldTypeMeta(type);
    const newField = {
      id: "fl_" + Math.random().toString(36).slice(2, 9),
      label: meta.label,
      type,
      required: false
    };
    if (["dropdown","multi","radio"].includes(type)) newField.options = ["Option 1", "Option 2"];
    saveFieldsNow([...(active.fields || []), newField]);
  };
  const removeField = (id) => active && saveFieldsNow((active.fields || []).filter(f => f.id !== id));
  const moveField = (id, dir) => {
    if (!active) return;
    const next = [...(active.fields || [])];
    const idx = next.findIndex(f => f.id === id);
    const tgt = idx + dir;
    if (tgt < 0 || tgt >= next.length) return;
    [next[idx], next[tgt]] = [next[tgt], next[idx]];
    saveFieldsNow(next);
  };
  const updateField = (id, patch) => active && saveFieldsNow((active.fields || []).map(f => f.id === id ? Object.assign({}, f, patch) : f));

  // Publish: save immediately, no debounce.
  const togglePublish = async () => {
    if (!active) return;
    const next = !active.published;
    setForms(prev => prev.map(f => f.id === activeId ? Object.assign({}, f, { published: next }) : f));
    if (flushTimerRef.current) { clearTimeout(flushTimerRef.current); flushTimerRef.current = null; }
    const pending = Object.assign({}, pendingPatchRef.current[activeId] || {}, { published: next });
    delete pendingPatchRef.current[activeId];
    const res = await SB.from('forms').update(pending).eq('id', activeId);
    if (res.error) { toast.push("Couldn't update: " + res.error.message); return; }
    toast.push(next ? "Form published" : "Form unpublished");
  };

  const createFromTemplate = async (templateId) => {
    if (!ws?.id) return;
    const tpl = FORM_TEMPLATES.find(t => t.id === templateId) || FORM_TEMPLATES[0];
    const row = Object.assign({ workspace_id: ws.id, published: false }, tpl.seed);
    const res = await SB.from('forms').insert(row).select().single();
    if (res.error) { toast.push("Couldn't create form: " + res.error.message); return; }
    setForms(prev => [...prev, res.data]);
    setActiveId(res.data.id);
    setShowTemplates(false);
    toast.push(`Created "${res.data.name}"`);
  };

  const deleteActive = async () => {
    if (!active) return;
    if (!window.confirm(`Delete "${active.name}"? This will archive it (existing bookings keep their reference).`)) return;
    const res = await SB.from('forms').update({ archived_at: new Date().toISOString() }).eq('id', active.id);
    if (res.error) { toast.push("Couldn't delete: " + res.error.message); return; }
    setForms(prev => prev.filter(f => f.id !== active.id));
    setActiveId(prev => {
      const next = forms.find(f => f.id !== active.id);
      return next ? next.id : null;
    });
    toast.push("Form deleted");
  };

  return (
    <div className="px-5 lg:px-7 py-7 max-w-[1500px] mx-auto">
      <PageHeader
        eyebrow="Customer-facing"
        title="Booking Forms"
        subtitle="Edit content, questions, and availability for each booking card on your website."
        actions={
          <Button icon="plus" onClick={() => setShowTemplates(true)}>New form</Button>
        }
      />

      {loading ? (
        <div className="py-16 text-center text-[12.5px] text-ink/50">Loading forms…</div>
      ) : forms.length === 0 ? (
        <div className="rounded-lg border border-dashed border-ink/[0.12] bg-white p-12 text-center">
          <div className="font-display text-[20px] mb-1">No forms yet</div>
          <p className="text-[13px] text-ink/55 mb-5 max-w-md mx-auto">
            A form is the card your customers fill out on your website to request a booking. Pick a starting template — you can edit everything afterwards.
          </p>
          <Button icon="plus" onClick={() => setShowTemplates(true)}>Create your first form</Button>
        </div>
      ) : (
        <div className="grid lg:grid-cols-[260px_1fr] gap-5">
          {/* Form list */}
          <aside className="lg:sticky lg:top-[72px] self-start">
            <div className="rounded-lg border border-ink/[0.06] bg-white overflow-hidden">
              {forms.map((f, i) => (
                <button
                  key={f.id}
                  onClick={() => setActiveId(f.id)}
                  className={`w-full text-left px-4 py-3 ${i ? "border-t border-ink/[0.06]" : ""} ${f.id === activeId ? "bg-ink/[0.04]" : "hover:bg-ink/[0.02]"}`}
                >
                  <div className="flex items-center justify-between gap-2">
                    <span className="font-medium text-[13.5px] truncate">{f.name}</span>
                    {f.published ? <Badge tone="ok" dot>Published</Badge> : <Badge tone="neutral">Draft</Badge>}
                  </div>
                  <div className="text-[11.5px] text-ink/50 mt-1 flex items-center gap-2">
                    <span>{(f.fields || []).length} questions</span>
                    <span className="text-ink/30">·</span>
                    <span>{f.duration_min} min</span>
                  </div>
                </button>
              ))}
            </div>
          </aside>

          {/* Editor */}
          <div className="grid xl:grid-cols-[1fr_440px] gap-5">
            {active ? (
              <FormEditor
                form={active}
                staff={staff}
                workspaceSlug={ws?.slug}
                saveState={saveState}
                onChange={updateActive}
                onAddField={addField}
                onUpdateField={updateField}
                onRemoveField={removeField}
                onMoveField={moveField}
                onPublishToggle={togglePublish}
                onDelete={deleteActive}
              />
            ) : (
              <div className="rounded-lg border border-ink/[0.06] bg-white p-8 text-[12.5px] text-ink/55">Pick a form to edit.</div>
            )}
            <div>
              <div className="text-[11px] uppercase tracking-[0.1em] text-ink/45 mb-3 flex items-center gap-2">
                <Icon name="eye" size={12} />
                Live preview
              </div>
              {active && <BookingFormPreview form={active} workspaceName={ws?.name} workspaceSlug={ws?.slug} />}
            </div>
          </div>
        </div>
      )}

      {/* Templates modal */}
      <Modal open={showTemplates} onClose={() => setShowTemplates(false)} title="Pick a starting template" subtitle="You can edit everything after." width={720}>
        <div className="grid sm:grid-cols-2 gap-3">
          {FORM_TEMPLATES.map((t) => (
            <button
              key={t.id}
              onClick={() => createFromTemplate(t.id)}
              className="text-left rounded-lg border border-ink/[0.08] bg-white p-4 hover:bg-white hover:border-ink/[0.20] transition"
            >
              <div className="flex items-start justify-between">
                <span className="font-medium text-[14px]">{t.name}</span>
                <Badge tone="neutral">{t.seed.fields.length} fields</Badge>
              </div>
              <div className="text-[12px] text-ink/55 mt-2">{t.desc}</div>
            </button>
          ))}
        </div>
      </Modal>
    </div>
  );
}

// ── Form Editor ───────────────────────────────────────────────────────────
function FormEditor({ form, staff, workspaceSlug, saveState, onChange, onAddField, onUpdateField, onRemoveField, onMoveField, onPublishToggle, onDelete }) {
  const [tab, setTab] = useState("content");
  const [editingField, setEditingField] = useState(null);
  const [showFieldPicker, setShowFieldPicker] = useState(false);
  const staffIds = form.staff_ids || [];
  const fields = form.fields || [];

  const publicUrl = workspaceSlug ? `${window.location.origin}/#/public/${workspaceSlug}` : null;
  const toggleStaff = (id) => onChange({ staff_ids: staffIds.includes(id) ? staffIds.filter(x => x !== id) : [...staffIds, id] });

  return (
    <div className="rounded-lg border border-ink/[0.06] bg-ink/[0.015]">
      <header className="flex items-center justify-between px-5 py-4 border-b border-ink/[0.06] gap-3">
        <div className="min-w-0 flex-1">
          <input
            value={form.name}
            onChange={(e) => onChange({ name: e.target.value })}
            className="bg-transparent font-display text-[24px] outline-none w-full"
          />
          <div className="flex items-center gap-2 text-[11.5px] text-ink/50 mt-0.5 flex-wrap">
            <span>{fields.length} questions</span>
            <span className="text-ink/25">·</span>
            <span>{form.duration_min} min</span>
            <span className="text-ink/25">·</span>
            <span>{form.confirmation_mode === "instant" ? "Instant confirmation" : "Manual approval"}</span>
            <span className="text-ink/25">·</span>
            <SaveStatus state={saveState} />
          </div>
        </div>
        <div className="flex items-center gap-3 flex-shrink-0">
          <Toggle checked={form.published} onChange={onPublishToggle} size="sm" label={
            <span className="inline-grid">
              <span className="col-start-1 row-start-1 invisible whitespace-nowrap">Published</span>
              <span className="col-start-1 row-start-1 whitespace-nowrap">{form.published ? "Published" : "Draft"}</span>
            </span>
          } />
          {publicUrl && (
            <Button size="sm" variant="secondary" icon="external-link" onClick={() => window.open(publicUrl, "_blank")}>
              Open
            </Button>
          )}
          <button onClick={onDelete} title="Delete form" className="text-ink/45 hover:text-danger h-8 w-8 grid place-items-center rounded-full hover:bg-ink/[0.05]">
            <Icon name="trash-2" size={14} />
          </button>
        </div>
      </header>

      <div className="px-5 pt-4">
        <Tabs value={tab} onChange={setTab} options={[
          { value: "content",      label: "Content" },
          { value: "questions",    label: "Questions" },
          { value: "availability", label: "Availability" },
          { value: "settings",     label: "Settings" }
        ]} />
      </div>

      {tab === "content" && (
        <div className="p-5 grid sm:grid-cols-2 gap-4">
          <Field label="Public title" hint="Shown to customers on your website">
            <Input value={form.public_title} onChange={(e) => onChange({ public_title: e.target.value })} />
          </Field>
          <Field label="Internal name" hint="Visible only to your team">
            <Input value={form.name} onChange={(e) => onChange({ name: e.target.value })} />
          </Field>
          <Field label="Description" className="sm:col-span-2">
            <Textarea value={form.description || ""} onChange={(e) => onChange({ description: e.target.value })} placeholder="Tell customers what to expect…" />
          </Field>
          <Field label="Duration">
            <div className="flex items-center gap-2">
              <Input type="number" className="w-28" value={form.duration_min} onChange={(e) => onChange({ duration_min: Math.max(5, +e.target.value || 0) })} />
              <span className="text-[12.5px] text-ink/55">minutes</span>
            </div>
          </Field>
          <Field label="Buffer between bookings" hint="Time blocked off after each booking">
            <div className="flex items-center gap-2">
              <Input type="number" className="w-28" value={form.buffer_min} onChange={(e) => onChange({ buffer_min: Math.max(0, +e.target.value || 0) })} />
              <span className="text-[12.5px] text-ink/55">minutes</span>
            </div>
          </Field>
        </div>
      )}

      {tab === "questions" && (
        <div className="p-5">
          <div className="flex items-center justify-between mb-3">
            <div className="text-[12px] text-ink/55">Reorder, edit, or remove. Customers see them in order.</div>
            <Button size="sm" variant="secondary" icon="plus" onClick={() => setShowFieldPicker(true)}>Add question</Button>
          </div>
          {fields.length === 0 ? (
            <div className="text-[12.5px] text-ink/45 text-center py-6">No questions yet. Add the first one →</div>
          ) : (
            <div className="flex flex-col gap-1.5">
              {fields.map((field, idx) => (
                <FieldRow
                  key={field.id}
                  field={field}
                  onEdit={() => setEditingField(field)}
                  onRemove={() => onRemoveField(field.id)}
                  onMoveUp={() => onMoveField(field.id, -1)}
                  onMoveDown={() => onMoveField(field.id, 1)}
                  first={idx === 0}
                  last={idx === fields.length - 1}
                />
              ))}
            </div>
          )}
        </div>
      )}

      {tab === "availability" && (
        <div className="p-5 grid sm:grid-cols-2 gap-4">
          <Field label="Confirmation">
            <Select value={form.confirmation_mode} onChange={(e) => onChange({ confirmation_mode: e.target.value })}>
              <option value="instant">Instant — auto-confirm</option>
              <option value="manual">Manual — require approval</option>
            </Select>
          </Field>
          <div /> {/* spacer */}
          <div className="sm:col-span-2">
            <div className="text-[12px] font-medium text-ink/75 mb-2">Assigned staff</div>
            {staff.length === 0 ? (
              <div className="text-[12.5px] text-ink/45">No staff members yet. Add them under Settings → Team.</div>
            ) : (
              <div className="flex flex-wrap gap-2">
                {staff.map((s) => {
                  const on = staffIds.includes(s.id);
                  return (
                    <button
                      key={s.id}
                      onClick={() => toggleStaff(s.id)}
                      className={`inline-flex items-center gap-2 h-8 pl-1 pr-3 rounded-full border transition ${on ? "border-accent/40 bg-accent/[0.10]" : "border-ink/10 hover:bg-ink/[0.02]"}`}
                    >
                      <Avatar name={s.name} size={22} />
                      <span className="text-[12px]">{s.name}</span>
                      {on && <Icon name="check" size={11} className="text-accent" />}
                    </button>
                  );
                })}
              </div>
            )}
          </div>
        </div>
      )}

      {tab === "settings" && (
        <div className="p-5">
          <div className="rounded-md border border-ink/[0.06] divide-y divide-ink/[0.06]">
            <SettingRow label="Allow rescheduling" hint="Customer can change date/time after booking"><LocalToggle defaultChecked={true} size="sm" /></SettingRow>
            <SettingRow label="Allow cancellation" hint="Customer can cancel up to 24h before"><LocalToggle defaultChecked={true} size="sm" /></SettingRow>
            <SettingRow label="Require phone number" hint="Phone is required even if not in form"><LocalToggle defaultChecked={false} size="sm" /></SettingRow>
            <SettingRow label="Send to Google Calendar" hint="Bookings appear on connected calendar"><LocalToggle defaultChecked={false} size="sm" /></SettingRow>
            <SettingRow label="Collect payment at booking" hint="Requires Stripe connection (not configured)"><LocalToggle defaultChecked={false} size="sm" /></SettingRow>
          </div>
          <p className="text-[11.5px] text-ink/45 mt-3">Settings above are visual placeholders — we'll wire them when their underlying features land.</p>
        </div>
      )}

      <Modal open={showFieldPicker} onClose={() => setShowFieldPicker(false)} title="Add a question" subtitle="Question type" width={560}>
        <div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
          {FIELD_TYPES.map((t) => (
            <button
              key={t.id}
              onClick={() => { onAddField(t.id); setShowFieldPicker(false); }}
              className="flex items-center gap-2.5 px-3 py-2.5 rounded-md border border-ink/[0.06] hover:bg-white hover:border-ink/[0.12] text-left transition"
            >
              <div className="h-7 w-7 grid place-items-center rounded bg-white">
                <Icon name={t.icon} size={13} className="text-ink/75" />
              </div>
              <span className="text-[12.5px]">{t.label}</span>
            </button>
          ))}
        </div>
      </Modal>

      <Drawer open={!!editingField} onClose={() => setEditingField(null)} title="Edit question" subtitle="Question settings" width={420} actions={
        <Button onClick={() => setEditingField(null)}>Done</Button>
      }>
        {editingField && (
          <FieldEditor
            field={editingField}
            onChange={(patch) => {
              onUpdateField(editingField.id, patch);
              setEditingField(Object.assign({}, editingField, patch));
            }}
          />
        )}
      </Drawer>
    </div>
  );
}

function SaveStatus({ state }) {
  if (state.error) return <span className="text-danger">{state.error}</span>;
  if (state.saving) return <span className="inline-flex items-center gap-1"><span className="h-1 w-1 rounded-full bg-ink/40 pulse-dot" />Saving…</span>;
  if (state.savedAt) return <span className="text-ink/45">Saved</span>;
  return <span className="text-ink/30">All changes saved</span>;
}

function SettingRow({ label, hint, children }) {
  return (
    <div className="flex items-center justify-between px-4 py-3">
      <div>
        <div className="text-[13px]">{label}</div>
        <div className="text-[11.5px] text-ink/50">{hint}</div>
      </div>
      {children}
    </div>
  );
}

function FieldRow({ field, onEdit, onRemove, onMoveUp, onMoveDown, first, last }) {
  const type = fieldTypeMeta(field.type);
  return (
    <div className="group flex items-center gap-3 px-3 py-2 rounded-md bg-white border border-ink/[0.06] hover:bg-white">
      <span className="text-ink/40"><Icon name="grip-vertical" size={14} /></span>
      <div className="h-7 w-7 grid place-items-center rounded bg-ink/[0.04]">
        <Icon name={type.icon} size={12} className="text-ink/70" />
      </div>
      <div className="flex-1 min-w-0">
        <div className="text-[13px] truncate">{field.label}</div>
        <div className="text-[11px] text-ink/50">{type.label}{field.required && " · required"}</div>
      </div>
      <div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition">
        <button onClick={onMoveUp} disabled={first} className="p-1.5 text-ink/55 hover:text-ink disabled:opacity-30"><Icon name="chevron-up" size={12} /></button>
        <button onClick={onMoveDown} disabled={last} className="p-1.5 text-ink/55 hover:text-ink disabled:opacity-30"><Icon name="chevron-down" size={12} /></button>
        <button onClick={onEdit} className="p-1.5 text-ink/55 hover:text-ink"><Icon name="pencil" size={12} /></button>
        <button onClick={onRemove} className="p-1.5 text-ink/55 hover:text-[#D69898]"><Icon name="trash-2" size={12} /></button>
      </div>
    </div>
  );
}

function FieldEditor({ field, onChange }) {
  const hasOptions = ["dropdown","multi","radio"].includes(field.type);
  return (
    <div className="flex flex-col gap-4">
      <Field label="Label" required>
        <Input value={field.label} onChange={(e) => onChange({ label: e.target.value })} />
      </Field>
      <Field label="Type">
        <Select value={field.type} onChange={(e) => onChange({ type: e.target.value })}>
          {FIELD_TYPES.map(t => <option key={t.id} value={t.id}>{t.label}</option>)}
        </Select>
      </Field>
      <Field label="Placeholder">
        <Input value={field.placeholder || ""} onChange={(e) => onChange({ placeholder: e.target.value })} placeholder="Optional helper text" />
      </Field>
      {hasOptions && (
        <Field label="Options" hint="One per line">
          <Textarea
            value={(field.options || []).join("\n")}
            onChange={(e) => onChange({ options: e.target.value.split("\n").filter(Boolean) })}
            placeholder={"Option 1\nOption 2\nOption 3"}
          />
        </Field>
      )}
      <div className="border-t border-ink/[0.06] pt-4">
        <Toggle checked={field.required} onChange={(v) => onChange({ required: v })} label="Required" hint="Customer must answer to submit" />
      </div>
    </div>
  );
}

// ── Live preview: mirrors the actual public booking card so the user can
// see what their customers will see. Keep this visually identical to
// pages-public.jsx so the preview stays honest.
function BookingFormPreview({ form, workspaceName, workspaceSlug }) {
  const fields = form.fields || [];
  return (
    <div className="rounded-2xl overflow-hidden border border-ink/[0.08] shadow-card bg-white">
      {/* Faux browser chrome */}
      <div className="bg-ink/[0.04] border-b border-ink/[0.06] px-3 py-2 flex items-center gap-2">
        <div className="flex items-center gap-1">
          <span className="h-2 w-2 rounded-full bg-ink/15" />
          <span className="h-2 w-2 rounded-full bg-ink/15" />
          <span className="h-2 w-2 rounded-full bg-ink/15" />
        </div>
        <div className="ml-1 text-[10.5px] text-ink/45 font-mono truncate">{workspaceSlug ? `/${workspaceSlug}` : "/your-slug"}</div>
      </div>

      {/* Apple-style content matching the real public page */}
      <div className="bg-paper text-ink p-5 antialiased">
        {/* Stepper */}
        <ol className="flex items-center gap-1.5 mb-4">
          {[1, 2, 3, 4].map((n, i) => (
            <React.Fragment key={n}>
              <li className={`inline-flex items-center gap-1.5 ${n === 1 ? "text-ink" : "text-ink/35"}`}>
                <span className={`h-4 w-4 grid place-items-center rounded-full text-[9px] font-medium ${n === 1 ? "bg-ink text-white" : "border border-ink/15 bg-white"}`}>{n}</span>
              </li>
              {i < 3 && <div className="h-px w-4 bg-ink/10" />}
            </React.Fragment>
          ))}
        </ol>

        {/* The card */}
        <div className="rounded-xl bg-white border border-ink/[0.06] shadow-card p-5">
          <div className="text-[10px] uppercase tracking-[0.12em] text-ink/45">Step 1 of 4</div>
          <h3 className="font-display text-[22px] tracking-tight leading-tight mt-1">{form.public_title || form.name}</h3>
          {form.description && <p className="mt-1.5 text-[12.5px] text-ink/55 leading-relaxed">{form.description}</p>}

          <div className="mt-4 flex flex-col gap-3">
            {fields.slice(0, 5).map((f) => <PreviewField key={f.id} field={f} />)}
            {fields.length > 5 && (
              <div className="text-[11px] text-ink/45">+ {fields.length - 5} more {fields.length - 5 === 1 ? "question" : "questions"} on next step</div>
            )}
          </div>

          <div className="mt-5 flex justify-end">
            <button className="h-9 px-4 rounded-full bg-ink text-white text-[12.5px] font-medium inline-flex items-center gap-1.5">
              Continue <Icon name="arrow-right" size={11} />
            </button>
          </div>
        </div>

        <div className="mt-3 text-[10.5px] text-ink/45 text-center">{workspaceName || "Your business"} · Booking by Vale</div>
      </div>
    </div>
  );
}

// Field "preview" — matches the input styling used on the real public page.
function PreviewField({ field }) {
  const Lab = () => (
    <span className="text-[10.5px] uppercase tracking-[0.1em] text-ink/55">
      {field.label}{field.required && <span className="text-ink/30"> *</span>}
    </span>
  );
  const inputCls = "h-9 w-full bg-white border border-ink/[0.10] rounded-md px-2.5 text-[12.5px] text-ink placeholder-ink/35 outline-none focus:border-ink/40";

  if (field.type === "checkbox") {
    return (
      <label className="inline-flex items-center gap-2 text-[12.5px]">
        <span className="h-4 w-4 rounded-md border border-ink/25" />
        {field.label}
      </label>
    );
  }
  if (field.type === "radio") {
    return (
      <div className="flex flex-col gap-1">
        <Lab />
        <div className="flex flex-col gap-1.5 mt-1">
          {(field.options || []).map((o, i) => (
            <label key={o} className="inline-flex items-center gap-2 text-[12.5px]">
              <span className={`h-3.5 w-3.5 rounded-full border ${i === 0 ? "border-ink bg-ink/10" : "border-ink/25"} grid place-items-center`}>{i === 0 && <span className="h-1.5 w-1.5 rounded-full bg-ink" />}</span>
              {o}
            </label>
          ))}
        </div>
      </div>
    );
  }
  if (field.type === "multi") {
    return (
      <div className="flex flex-col gap-1">
        <Lab />
        <div className="flex flex-wrap gap-1.5 mt-1">
          {(field.options || []).map((o, i) => (
            <span key={o} className={`px-2.5 h-7 grid place-items-center rounded-md text-[11.5px] border ${i === 0 ? "bg-ink text-white border-ink" : "border-ink/[0.10] bg-white text-ink/80"}`}>{o}</span>
          ))}
        </div>
      </div>
    );
  }
  if (field.type === "party") {
    return (
      <div className="flex flex-col gap-1">
        <Lab />
        <div className="flex items-center gap-1.5 mt-1">
          {[1,2,3,4,5,"6+"].map((n, i) => (
            <span key={n} className={`h-8 w-9 grid place-items-center rounded-md text-[12px] border ${i === 1 ? "bg-ink text-white border-ink" : "border-ink/[0.10] bg-white"}`}>{n}</span>
          ))}
        </div>
      </div>
    );
  }

  let control;
  switch (field.type) {
    case "long":
      control = <textarea className="w-full bg-white border border-ink/[0.10] rounded-md p-2.5 text-[12.5px] resize-none outline-none" rows="3" placeholder={field.placeholder || "Type here…"} />;
      break;
    case "dropdown":
      control = (
        <select className={inputCls + " pr-8 appearance-none"} defaultValue="">
          <option value="">Choose…</option>
          {(field.options || []).map(o => <option key={o}>{o}</option>)}
        </select>
      );
      break;
    case "vehicle":
      control = (
        <select className={inputCls + " pr-8 appearance-none"} defaultValue="">
          <option value="">Choose…</option><option>Side-by-side</option><option>ATV</option><option>Snowmobile</option><option>Watercraft</option>
        </select>
      );
      break;
    case "service":
      control = (
        <select className={inputCls + " pr-8 appearance-none"} defaultValue="">
          <option value="">Choose…</option><option>Maintenance</option><option>Repair</option><option>Inspection</option>
        </select>
      );
      break;
    case "date":
      control = <input type="text" className={inputCls} placeholder="dd / mm / yyyy" />;
      break;
    case "time":
      control = <input type="text" className={inputCls} placeholder="--:--" />;
      break;
    case "address":
      control = <input className={inputCls} placeholder="Street address" />;
      break;
    case "number":
      control = <input type="number" className={inputCls} placeholder={field.placeholder || ""} />;
      break;
    case "email":
      control = <input type="email" className={inputCls} placeholder="you@example.com" />;
      break;
    case "phone":
      control = <input type="tel" className={inputCls} placeholder="+32 …" />;
      break;
    default:
      control = <input className={inputCls} placeholder={field.placeholder || ""} />;
  }
  return (
    <label className="flex flex-col gap-1.5">
      <Lab />
      {control}
    </label>
  );
}

Object.assign(window, { BookingFormsPage, BookingFormPreview, PreviewField, FIELD_TYPES, FORM_TEMPLATES });
