import React, { useEffect, useMemo, useState } from "react";
import axios from "axios";
import { Button } from "@/prime-react";
import { Column } from "@/prime-react";
import { DataTable } from "@/prime-react";
import { ProgressSpinner } from "@/prime-react";
import { Dialog } from "@/prime-react";
import { InputText } from "@/prime-react";
import { InputTextarea } from "@/prime-react";
import { InputNumber } from "@/prime-react";
import { Dropdown } from "@/prime-react";
import { MultiSelect } from "@/prime-react";
import { useConfirm } from "../../shared/ConfirmDialog";
import { DETAIL_SCOPE, DETAIL_FIELD_TYPE, DETAIL_FIELD_OPTION_BACKED, DETAIL_FIELD_FILE_BACKED } from "@/shared/status";

const TYPE_OPTIONS = [
    { label: "Short text",   value: DETAIL_FIELD_TYPE.STRING },
    { label: "Long text",    value: DETAIL_FIELD_TYPE.TEXT },
    { label: "Email",        value: DETAIL_FIELD_TYPE.EMAIL },
    { label: "Phone",        value: DETAIL_FIELD_TYPE.PHONE },
    { label: "URL",          value: DETAIL_FIELD_TYPE.URL },
    { label: "Whole number", value: DETAIL_FIELD_TYPE.INTEGER },
    { label: "Decimal",      value: DETAIL_FIELD_TYPE.DECIMAL },
    { label: "Yes / No",     value: DETAIL_FIELD_TYPE.BOOL },
    { label: "Date",         value: DETAIL_FIELD_TYPE.DATE },
    { label: "Time",         value: DETAIL_FIELD_TYPE.TIME },
    { label: "Date & time",  value: DETAIL_FIELD_TYPE.DATETIME },
    { label: "Select",       value: DETAIL_FIELD_TYPE.SELECT },
    { label: "Multi-select", value: DETAIL_FIELD_TYPE.MULTISELECT },
    { label: "File upload",  value: DETAIL_FIELD_TYPE.FILE },
    { label: "Image upload", value: DETAIL_FIELD_TYPE.IMAGE },
    { label: "JSON",         value: DETAIL_FIELD_TYPE.JSON },
];

const TYPE_BADGE = {
    [DETAIL_FIELD_TYPE.STRING]:      "pt-b-blue",
    [DETAIL_FIELD_TYPE.TEXT]:        "pt-b-grey",
    [DETAIL_FIELD_TYPE.EMAIL]:       "pt-b-blue",
    [DETAIL_FIELD_TYPE.PHONE]:       "pt-b-blue",
    [DETAIL_FIELD_TYPE.URL]:         "pt-b-blue",
    [DETAIL_FIELD_TYPE.INTEGER]:     "pt-b-amber",
    [DETAIL_FIELD_TYPE.DECIMAL]:     "pt-b-amber",
    [DETAIL_FIELD_TYPE.BOOL]:        "pt-b-green",
    [DETAIL_FIELD_TYPE.DATE]:        "pt-b-red",
    [DETAIL_FIELD_TYPE.TIME]:        "pt-b-red",
    [DETAIL_FIELD_TYPE.DATETIME]:    "pt-b-red",
    [DETAIL_FIELD_TYPE.SELECT]:      "pt-b-brand",
    [DETAIL_FIELD_TYPE.MULTISELECT]: "pt-b-brand",
    [DETAIL_FIELD_TYPE.FILE]:        "pt-b-grey",
    [DETAIL_FIELD_TYPE.IMAGE]:       "pt-b-grey",
    [DETAIL_FIELD_TYPE.JSON]:        "pt-b-grey",
};

const typeLabel = (t) => TYPE_OPTIONS.find(o => o.value === t)?.label || t;

const blank = {
    id: null,
    // Everyone by default: a field admin adds without thinking about targeting should be asked of
    // everyone, which is what the two global configs always did.
    scope: DETAIL_SCOPE.GLOBAL,
    target_ids: [],
    service_id: null,
    key: "",
    label: "",
    description: "",
    type: DETAIL_FIELD_TYPE.STRING,
    options: "",
    required: false,
    order: 0,
    enabled: true,
};

const SVG = {
    plus:    '<line x1="12" x2="12" y1="5" y2="19"/><line x1="5" x2="19" y1="12" y2="12"/>',
    refresh: '<path d="M3 12a9 9 0 1 0 9-9 9 9 0 0 0-6.36 2.64L3 8"/><polyline points="3 3 3 8 8 8"/>',
    search:  '<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>',
    edit:    '<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>',
    trash:   '<polyline points="3 6 5 6 21 6"/><path d="M19 6l-2 14a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2L5 6"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>',
    info:    '<circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/>',
    inbox:   '<polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/>',
    settings:'<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>',
    user:    '<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',
    building:'<path d="M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z"/><path d="M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2"/><path d="M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2"/><path d="M10 6h4"/><path d="M10 10h4"/><path d="M10 14h4"/>',
    chart:   '<path d="M3 3v18h18"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/>',
};
function Icon({ name, size = 16 }) {
    return (
        <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
             strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}
             dangerouslySetInnerHTML={{ __html: SVG[name] || "" }} />
    );
}

const DetailConfigPage = ({
    title       = "Detail Config",
    subtitle    = "Define which fields participants can fill.",
    icon        = "settings",
    entityName  = "field",
    endpointPrefix,
    showServiceColumn = false,
    targetLabel   = "rows",
    targetEndpoint = null,
}) => {
    const [items, setItems]                 = useState([]);
    const [services, setServices]           = useState([]);
    const [isLoading, setIsLoading]         = useState(true);
    const [dialogVisible, setDialogVisible] = useState(false);
    const [item, setItem]                   = useState({ ...blank });
    const [error, setError]                 = useState(null);
    const [search, setSearch]               = useState("");
    const [confirmEl, confirm]              = useConfirm();

    // Detail fields live in their own `info` namespace, so they cannot collide with the parent
    // row's columns — only with each other, and only because one `info` key holds one value. The
    // MongoDB unique index is what refuses it; this just says so beside the field first.
    const keyTaken = useMemo(() => {
        const k = String(item.key || "").trim().toLowerCase();
        if (!k) return null;
        const clash = items.some(r => String(r.key || "").toLowerCase() === k && (r._id ?? r.id) !== item.id);
        return clash ? `A field with the key "${k}" already exists.` : null;
    }, [item.key, item.id, items]);

    const [targets, setTargets] = useState([]);

    const serviceById = useMemo(() => {
        const m = {};
        services.forEach(s => { m[s.id] = s; });
        return m;
    }, [services]);

    const list = async () => {
        setIsLoading(true);
        try {
            const res = await axios.get(`${endpointPrefix}/list`);
            setItems(res.data || []);
        } catch (e) {
            console.error("Failed to load:", e);
        } finally {
            setIsLoading(false);
        }
    };

    // Only needed for scope=Selected; fetched once so switching the radio is instant.
    const loadTargets = async () => {
        if (!targetEndpoint) return;
        try {
            const res = await axios.get(targetEndpoint);
            const rows = Array.isArray(res.data) ? res.data : (res.data?.items || []);
            setTargets(rows.map(r => ({ id: Number(r.id), name: r.name || r.email || `#${r.id}` })));
        } catch (e) {
            console.error("Failed to load targets:", e);
        }
    };

    const loadServices = async () => {
        if (!showServiceColumn) return;
        try {
            const res = await axios.get(`${endpointPrefix}/services`);
            setServices(res.data || []);
        } catch (e) {
            console.error("Failed to load services:", e);
        }
    };

    useEffect(() => {
        list();
        loadServices();
        loadTargets();
    }, []);

    const openAdd = () => {
        setItem({ ...blank });
        setError(null);
        setDialogVisible(true);
    };

    const openEdit = (row) => {
        setItem({
            id: row._id ?? row.id,
            service_id: row.service_id ?? null,
            scope: row.scope ?? DETAIL_SCOPE.GLOBAL,
            target_ids: (row.target_ids ?? []).map(Number),
            key: row.key ?? "",
            label: row.label ?? "",
            description: row.description ?? "",
            type: row.type ?? DETAIL_FIELD_TYPE.STRING,
            options: Array.isArray(row.options) ? row.options.join(", ") : "",
            required: !!row.required,
            order: row.order ?? 0,
            enabled: row.enabled ?? true,
        });
        setError(null);
        setDialogVisible(true);
    };

    const buildPayload = () => {
        const optionsArr = item.options
            ? item.options.split(",").map(s => s.trim()).filter(Boolean)
            : null;
        const p = {
            key: item.key,
            label: item.label,
            description: item.description || null,
            type: item.type,
            options: optionsArr,
            required: item.required,
            order: item.order,
            enabled: item.enabled,
        };
        p.scope = item.scope;
        // Sent empty unless Selected, so switching back to Everyone cannot leave stale targets
        // behind that reappear if someone flips it again.
        p.target_ids = item.scope === DETAIL_SCOPE.SELECTED ? item.target_ids : [];
        if (showServiceColumn) p.service_id = item.service_id;
        return p;
    };

    const save = async () => {
        // The server refuses it too; stopping here keeps the message next to the field rather
        // than in a toast at the top of the dialog.
        if (keyTaken) { setError(keyTaken); return; }
        try {
            const payload = buildPayload();
            if (item.id) {
                await axios.put(`${endpointPrefix}/edit`, { id: item.id, ...payload });
            } else {
                await axios.post(`${endpointPrefix}/add`, payload);
            }
            await list();
            setDialogVisible(false);
            setError(null);
        } catch (e) {
            console.error("Save error:", e);
            setError(e.response?.data?.message || e.message || "Save failed.");
        }
    };

    const remove = async (row) => {
        const ok = await confirm({
            title: `Delete field "${row.key}"?`,
            confirmLabel: "Delete",
            destructive: true,
        });
        if (!ok) return;
        try {
            await axios.post(`${endpointPrefix}/delete`, { id: row._id ?? row.id });
            await list();
        } catch (e) {
            console.error("Delete error:", e);
        }
    };

    const filteredItems = useMemo(() => {
        if (!search.trim()) return items;
        const q = search.toLowerCase();
        return items.filter(r =>
            String(r.key || "").toLowerCase().includes(q) ||
            String(r.label || "").toLowerCase().includes(q) ||
            String(r.type || "").toLowerCase().includes(q)
        );
    }, [items, search]);

    // ------------ Column bodies ------------
    const keyBody       = (row) => <span className="pt-key-chip">{row.key}</span>;
    const labelBody     = (row) => <span style={{ fontWeight: 600, color: "var(--ink)" }}>{row.label}</span>;
    const typeBody      = (row) => <span className={`pt-badge ${TYPE_BADGE[row.type] || "pt-b-grey"}`}>{typeLabel(row.type)}</span>;
    const optionsBody   = (row) => Array.isArray(row.options) && row.options.length
        ? <div className="pt-pill-row">
            {row.options.slice(0, 3).map((o, i) => <span key={i} className="pt-badge pt-b-grey">{o}</span>)}
            {row.options.length > 3 && <span className="pt-badge pt-b-grey">+{row.options.length - 3}</span>}
          </div>
        : <span style={{ color: "var(--faint)" }}>—</span>;
    const requiredBody  = (row) => row.required
        ? <span className="pt-badge pt-b-amber"><span className="pt-dot"></span>Required</span>
        : <span className="pt-badge pt-b-grey">Optional</span>;
    const orderBody     = (row) => <span className="pt-mono pt-tnum" style={{ color: "var(--ink-2)" }}>{row.order ?? 0}</span>;
    const enabledBody   = (row) => row.enabled
        ? <span className="pt-badge pt-b-green"><span className="pt-dot"></span>On</span>
        : <span className="pt-badge pt-b-red"><span className="pt-dot"></span>Off</span>;
    const serviceBody   = (row) => {
        const s = serviceById[row.service_id];
        return s
            ? <span><span className="pt-key-chip" style={{ marginRight: 6 }}>#{s.id}</span>{s.name}</span>
            : <span style={{ color: "var(--faint)" }}>—</span>;
    };
    const manageBody    = (row) => (
        <div className="pt-row-actions">
            <button className="pt-icon-btn" onClick={() => openEdit(row)} title="Edit"><Icon name="edit" size={14} /></button>
            <button className="pt-icon-btn is-danger" onClick={() => remove(row)} title="Delete"><Icon name="trash" size={14} /></button>
        </div>
    );

    // ------------ Empty state ------------
    const emptyTemplate = () => (
        <div className="pt-empty">
            <div className="pt-empty-ico"><Icon name="inbox" size={26} /></div>
            <h4>No {entityName}s yet</h4>
            <p>Add your first {entityName} to start collecting structured data.</p>
            <Button label={`Add ${entityName}`} icon="pi pi-plus" onClick={openAdd} />
        </div>
    );

    const Toggle = ({ label, hint, checked, onChange }) => (
        <button type="button" className={`pt-switch${checked ? " is-on" : ""}`} onClick={() => onChange(!checked)}>
            <div className="pt-switch-meta">
                <b>{label}</b>
                <small>{hint}</small>
            </div>
            <span className="pt-switch-toggle" />
        </button>
    );

    return (
        <div className="pt-fade-in">
            {/* Page header */}
            <div className="pt-page-head">
                <div className="pt-page-head-row">
                    <div className="pt-page-icon"><Icon name={icon} size={22} /></div>
                    <div>
                        <h2>{title}</h2>
                        <p>{subtitle}</p>
                    </div>
                </div>
                <span className="pt-count-chip">
                    {items.length} {items.length === 1 ? entityName : `${entityName}s`}
                </span>
            </div>

            {/* Info banner — surface the ADMIN-only rule */}
            <div className="pt-info-banner">
                <span className="pt-info-ico"><Icon name="info" size={14} /></span>
                <div>
                    <b>Admins only.</b> Fields defined here gate what shows up on the corresponding profile.
                    Toggle <b>Enabled</b> off to hide a field without losing its definition.
                </div>
            </div>

            {/* Card: toolbar + table */}
            <div className="pt-card">
                <div className="pt-toolbar">
                    <div className="pt-toolbar-search">
                        <span className="pt-search-ico"><Icon name="search" size={14} /></span>
                        <input
                            type="text"
                            placeholder={`Search by key, label or type…`}
                            value={search}
                            onChange={(e) => setSearch(e.target.value)}
                        />
                    </div>
                    <div className="pt-toolbar-actions">
                        <Button onClick={list}   icon="pi pi-refresh" label="Refresh" className="p-button-sm p-button-secondary" />
                        <Button onClick={openAdd} icon="pi pi-plus"   label={`Add ${entityName}`} className="p-button-sm" />
                    </div>
                </div>

                {isLoading ? (
                    <div className="pt-empty">
                        <ProgressSpinner style={{ width: "2.2rem", height: "2.2rem" }} />
                        <p style={{ marginTop: 14 }}>Loading {entityName}s…</p>
                    </div>
                ) : (
                    <DataTable
                        value={filteredItems}
                        paginator={filteredItems.length > 10}
                        rows={10}
                        tableStyle={{ minWidth: "52rem" }}
                        emptyMessage={emptyTemplate}
                        removableSort
                    >
                        {showServiceColumn && <Column header="Service" body={serviceBody} />}
                        <Column header="Key"      body={keyBody}      sortable field="key" />
                        <Column header="Label"    body={labelBody}    sortable field="label" />
                        <Column header="Type"     body={typeBody}     sortable field="type" />
                        <Column header="Options"  body={optionsBody}  />
                        <Column header="Required" body={requiredBody} sortable field="required" />
                        <Column header="Order"    body={orderBody}    sortable field="order" />
                        <Column header="Status"   body={enabledBody}  sortable field="enabled" />
                        <Column header=""         body={manageBody}   style={{ width: 96, textAlign: "right" }} />
                    </DataTable>
                )}
            </div>

            {/* Add / Edit Dialog */}
            <Dialog
                visible={dialogVisible}
                onHide={() => setDialogVisible(false)}
                header={
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                        <div className="pt-page-icon" style={{ width: 32, height: 32, borderRadius: 9 }}>
                            <Icon name={item.id ? "edit" : "plus"} size={14} />
                        </div>
                        <div>
                            <div style={{ fontSize: 15, fontWeight: 700, fontFamily: "var(--mono)", color: "var(--ink)" }}>
                                {item.id ? `Edit ${entityName}` : `New ${entityName}`}
                            </div>
                            <div style={{ fontSize: 11.5, color: "var(--muted)", fontWeight: 500 }}>
                                {item.id ? "Update the field definition" : "Define a new field for this profile"}
                            </div>
                        </div>
                    </div>
                }
                style={{ width: "680px" }}
                breakpoints={{ "960px": "92vw" }}
                modal
                draggable={false}
            >
                <div className="form-body">
                    {error && (
                        <div className="pt-info-banner" style={{ background: "rgba(255,109,128,.1)", borderColor: "rgba(255,109,128,.28)", color: "#ff8a96", marginBottom: 14 }}>
                            <span className="pt-info-ico" style={{ background: "rgba(255,109,128,.18)", color: "#ff8a96" }}><Icon name="info" size={14} /></span>
                            <div>{String(error)}</div>
                        </div>
                    )}

                    {/* Section: Identity */}
                    <div className="pt-dialog-section">
                        <div className="pt-dialog-section-title">Identity</div>
                        <div className="pt-grid pt-g-2">
                            {showServiceColumn && (
                                <div className="form-group" style={{ gridColumn: "1 / -1" }}>
                                    <label className="form-label">Service</label>
                                    <Dropdown
                                        value={item.service_id}
                                        onChange={(e) => setItem({ ...item, service_id: e.value })}
                                        options={services}
                                        optionLabel="name"
                                        optionValue="id"
                                        placeholder="Select a service"
                                        className="w-full"
                                    />
                                </div>
                            )}
                            {/* Targeting. Spans the grid because the picker needs the width, and it
                                is the first thing to decide: it says who will ever be asked this. */}
                            <div className="form-group" style={{ gridColumn: "1 / -1" }}>
                                <label className="form-label">Asked of</label>
                                <Dropdown className="w-full" value={item.scope}
                                    options={[
                                        { label: `Everyone \u2014 every one of your ${targetLabel}`, value: DETAIL_SCOPE.GLOBAL },
                                        { label: `Selected ${targetLabel} only`, value: DETAIL_SCOPE.SELECTED },
                                    ]}
                                    onChange={(e) => setItem({ ...item, scope: e.value })} />
                                {item.scope === DETAIL_SCOPE.SELECTED && (
                                    <>
                                        <MultiSelect className="w-full" style={{ marginTop: 8 }}
                                            value={item.target_ids} options={targets}
                                            optionLabel="name" optionValue="id" display="chip" filter
                                            placeholder={`Choose ${targetLabel}`}
                                            onChange={(e) => setItem({ ...item, target_ids: e.value })} />
                                        {item.target_ids.length === 0 && (
                                            <small className="pt-hint">
                                                Choose at least one — a Selected field with no targets is stored but never asked.
                                            </small>
                                        )}
                                    </>
                                )}
                            </div>
                            <div className="form-group">
                                <label className="form-label">Key</label>
                                <InputText className={`w-full${keyTaken ? " p-invalid" : ""}`} value={item.key}
                                    onChange={(e) => setItem({ ...item, key: e.target.value })} placeholder="e.g. phone" />
                                {keyTaken && <small className="pt-field-error">{keyTaken}</small>}
                            </div>
                            <div className="form-group">
                                <label className="form-label">Label</label>
                                <InputText className="w-full" value={item.label}
                                    onChange={(e) => setItem({ ...item, label: e.target.value })} placeholder="e.g. Phone number" />
                            </div>
                            <div className="form-group" style={{ gridColumn: "1 / -1" }}>
                                <label className="form-label">Description <span className="pt-hint">(optional)</span></label>
                                <InputTextarea className="w-full" rows={2} value={item.description}
                                    onChange={(e) => setItem({ ...item, description: e.target.value })}
                                    placeholder="Help text shown beside the field — why it is collected, or how to fill it in." />
                            </div>
                        </div>
                    </div>

                    {/* Section: Type & Options */}
                    <div className="pt-dialog-section">
                        <div className="pt-dialog-section-title">Type &amp; options</div>
                        <div className="pt-grid pt-g-2">
                            <div className="form-group">
                                <label className="form-label">Field type</label>
                                <Dropdown value={item.type} options={TYPE_OPTIONS}
                                    onChange={(e) => setItem({ ...item, type: e.value })}
                                    className="w-full" />
                            </div>
                            <div className="form-group">
                                <label className="form-label">Display order</label>
                                <InputNumber value={item.order}
                                    onValueChange={(e) => setItem({ ...item, order: e.value ?? 0 })}
                                    className="w-full" />
                            </div>
                            {DETAIL_FIELD_OPTION_BACKED.includes(item.type) && (
                                <div className="form-group" style={{ gridColumn: "1 / -1" }}>
                                    <label className="form-label">Options (comma separated)</label>
                                    <InputText className="w-full" value={item.options}
                                        onChange={(e) => setItem({ ...item, options: e.target.value })}
                                        placeholder="e.g. small, medium, large" />
                                </div>
                            )}
                            {DETAIL_FIELD_FILE_BACKED.includes(item.type) && (
                                <div className="form-group" style={{ gridColumn: "1 / -1" }}>
                                    <div className="pt-hint">Stored as an upload descriptor — path, name, mime and size. The upload endpoint is not built yet.</div>
                                </div>
                            )}
                        </div>
                    </div>

                    {/* Section: Behavior */}
                    <div className="pt-dialog-section">
                        <div className="pt-dialog-section-title">Behavior</div>
                        <div className="pt-grid pt-g-2">
                            <div className="form-group">
                                <Toggle
                                    label="Required"
                                    hint="Users must provide a value"
                                    checked={item.required}
                                    onChange={(v) => setItem({ ...item, required: v })}
                                />
                            </div>
                            <div className="form-group">
                                <Toggle
                                    label="Enabled"
                                    hint="Off hides the field without deleting it"
                                    checked={item.enabled}
                                    onChange={(v) => setItem({ ...item, enabled: v })}
                                />
                            </div>
                        </div>
                    </div>

                    <div style={{ display: "flex", gap: 8, justifyContent: "flex-end", marginTop: 18, paddingTop: 14, borderTop: "1px solid rgba(63,224,255,.14)" }}>
                        <Button label="Cancel" icon="pi pi-times" onClick={() => setDialogVisible(false)} className="p-button-secondary" />
                        <Button label={item.id ? "Save changes" : "Create field"} icon="pi pi-check"
                            disabled={!!keyTaken || (item.scope === DETAIL_SCOPE.SELECTED && item.target_ids.length === 0)}
                            onClick={save} />
                    </div>
                </div>
            </Dialog>
            {confirmEl}
        </div>
    );
};

export default DetailConfigPage;
