/* NutriDMS, Compliance & Health Rules (list pages + allergen modal + Loraa assist)
   Wizards live in compliance-wizards.jsx. All tables are read-only for non-admins;
   Add / Edit / status toggles are gated to Admin & Super-admin. */

const { useState: useCoState, useMemo: useCoMemo, useEffect: useCoEffect, useRef: useCoRef } = React;

/* ───────── Shared atoms ───────── */
function CompTypeBadge({ type }) {
  const cls = { "Nutrition": "t-nutrition", "Health Tag": "t-healthtag", "Ingredient": "t-ingredient" }[type] || "t-nutrition";
  return <span className={`comp-type ${cls}`}>{type}</span>;
}
function CompSourceBadge({ source }) {
  const isCustom = /custom/i.test(source);
  return <span className={`comp-source ${isCustom ? "custom" : "dms"}`}>{isCustom ? "Custom" : "Regulatory"}</span>;
}
function CompSeverityText({ severity }) {
  return <span className={`comp-sev sev-${(severity || "").toLowerCase()}`}>{severity}</span>;
}
function CompStatusText({ status }) {
  return <span className={`comp-status ${status === "active" ? "on" : "off"}`}>{status === "active" ? "Active" : "Inactive"}</span>;
}

function CompStatCards({ cards }) {
  return (
    <div className="comp-stats">
      {cards.map((c, i) => (
        <div className="comp-stat" key={i}>
          <span className={`comp-stat-ic ${c.tone}`}><Icon name={c.icon} size={18} /></span>
          <div className="comp-stat-meta">
            <span className="comp-stat-k">{c.label}</span>
            <span className="comp-stat-v">{c.value}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

/* ───────── Hard rolling-pill rail (replaces the row hover popover) ───────── */
function CompPillRail({ items, tone }) {
  if (!items || !items.length) return <span className="comp-muted">—</span>;
  return (
    <div className="comp-pill-rail">
      {items.map((x, i) => <span className={`comp-rail-pill ${tone || ""}`} key={i}>{x}</span>)}
    </div>
  );
}

/* Kebab action menu — Edit + Enable/Disable when allowed, View always */
function CompKebab({ canEdit, onEdit, onView, onToggle, status }) {
  const [open, setOpen] = useCoState(false);
  const [pos, setPos] = useCoState(null);
  const ref = useCoRef(null);
  const btnRef = useCoRef(null);
  useCoEffect(() => {
    if (!open) return;
    const close = (e) => { if (btnRef.current && btnRef.current.contains(e.target)) return; if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const dismiss = () => setOpen(false);
    document.addEventListener("mousedown", close);
    window.addEventListener("scroll", dismiss, true);
    window.addEventListener("resize", dismiss);
    return () => {
      document.removeEventListener("mousedown", close);
      window.removeEventListener("scroll", dismiss, true);
      window.removeEventListener("resize", dismiss);
    };
  }, [open]);
  const toggle = () => {
    if (!open && btnRef.current) {
      const r = btnRef.current.getBoundingClientRect();
      setPos({ top: r.bottom + 6, left: Math.max(8, r.right - 150) });
    }
    setOpen((o) => !o);
  };
  const menu = open && pos ? (
    <div className="comp-kebab-menu" ref={ref} style={{ position: "fixed", top: pos.top, left: pos.left, right: "auto", zIndex: 200 }}>
      {canEdit && onEdit && <button onClick={() => { setOpen(false); onEdit(); }}><Icon name="square-pen" size={15} /> Edit</button>}
      <button onClick={() => { setOpen(false); onView && onView(); }}><Icon name="eye" size={15} /> View</button>
      {canEdit && onToggle && (status === "inactive"
        ? <button onClick={() => { setOpen(false); onToggle("active"); }}><Icon name="circle-check" size={15} /> Enable</button>
        : <button className="comp-kebab-danger" onClick={() => { setOpen(false); onToggle("inactive"); }}><Icon name="circle-slash" size={15} /> Disable</button>)}
    </div>
  ) : null;
  return (
    <div className="comp-kebab">
      <button ref={btnRef} className="comp-kebab-btn" onClick={toggle} title="Actions"><Icon name="more-vertical" size={16} /></button>
      {menu && ReactDOM.createPortal(menu, document.body)}
    </div>
  );
}

/* Loraa assist pill → centered popup (reuses cu-loraa styling). In compliance,
   Loraa drafts rule tables and explains how rules are used for validation. */
function CompLoraaAssist({ context, onDraft }) {
  const [open, setOpen] = useCoState(false);
  const [busy, setBusy] = useCoState(false);
  return (
    <>
      <button type="button" className="cu-loraa-pill cu-loraa-animated" style={{ margin: 0 }} onClick={() => setOpen(true)}>
        <span className="cu-loraa-logo sm"><img src="assets/loraa-logo.png" alt="Loraa" /></span>
        <span>Build with Loraa</span>
        <Icon name="chevron-down" size={14} />
      </button>
      {open && (
        <div className="cu-loraa-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) setOpen(false); }}>
          <div className="cu-loraa cu-loraa-pop cu-loraa-animated" role="dialog" aria-label="Loraa assistant">
            <div className="cu-loraa-pop-head">
              <span className="cu-loraa-logo"><img src="assets/loraa-logo.png" alt="Loraa" /></span>
              <strong>Loraa builds compliance rules</strong>
              <button type="button" className="cu-loraa-collapse" title="Collapse" onClick={() => setOpen(false)}><Icon name="x" size={16} /></button>
            </div>
            <p className="cu-loraa-pop-body">
              Loraa can draft a starting <strong>{context}</strong> from your library, suggested nutrient limits, linked health tags and allergen cross-links, then you refine and activate it.
            </p>
            {onDraft && (
              <button type="button" className="cu-loraa-analyze" disabled={busy} onClick={() => { setBusy(true); setTimeout(() => { setBusy(false); setOpen(false); onDraft(); }, 850); }}>
                {busy ? <><Icon name="loader" size={14} className="spin" /> Drafting…</> : <><Icon name="lightbulb" size={14} /> Draft a rule for me</>}
              </button>
            )}
            <div className="cu-loraa-pop-foot"><Icon name="info" size={13} stroke={2.4} /><span>Loraa also enforces these rules, running flags &amp; compliance checks whenever recipes and ingredients are created.</span></div>
          </div>
        </div>
      )}
    </>
  );
}

/* ───────── Rules table (Nutrient + Ingredient pages share this) ───────── */
function CompRulesPage({ title, addLabel, wizardType, embedded }) {
  const { role, toast, openCompliance } = useApp();
  const canEdit = canEditCompliance(role);
  const [data, setData] = useCoState(compLoad);
  const [q, setQ] = useCoState("");
  const [typeF, setTypeF] = useCoState("all");
  const [bulkBusy, setBulkBusy] = useCoState(false);
  const bulkFileRef = useCoRef(null);
  const rules = data.rules;

  const reload = () => setData(compLoad());
  React.useEffect(() => {
    const h = () => setData(compLoad());
    window.addEventListener("nutridms-compliance", h);
    if (typeof compSyncRemote === "function") {
      compSyncRemote().catch(() => {
        toast && toast("Live compliance rules could not be loaded.");
      });
    }
    return () => window.removeEventListener("nutridms-compliance", h);
  }, []);
  const filtered = useCoMemo(() => rules.filter((r) =>
    (typeF === "all" || r.type === typeF) &&
    (!q || r.name.toLowerCase().includes(q.toLowerCase()) || (r.desc || "").toLowerCase().includes(q.toLowerCase()))
  ), [rules, q, typeF]);

  const total = rules.length;
  const active = rules.filter((r) => r.status === "active").length;
  const linked = rules.reduce((n, r) => n + (r.tags ? r.tags.length : 0), 0);

  const openWizard = (mode, row) => openCompliance && openCompliance({ type: row ? typeForWizard(row.type) : wizardType, mode, row, onSaved: reload });

  const downloadTemplate = async () => {
    try {
      await compDownloadRuleTemplate();
      toast && toast("Nutrient rule template downloaded");
    } catch (error) {
      toast && toast((error && error.message) || "The rule template could not be downloaded.");
    }
  };
  const uploadRules = async (event) => {
    const input = event && event.target;
    const file = input && input.files && input.files[0];
    if (!file) return;
    setBulkBusy(true);
    try {
      const result = await compBulkUploadRuleFile(file);
      reload();
      toast && toast((result.imported || 0) + " nutrient rule" + (result.imported === 1 ? "" : "s") + " imported");
    } catch (error) {
      const first = error && error.data && Array.isArray(error.data.rows) && error.data.rows[0];
      const rowMessage = first && Array.isArray(first.errors) ? " Row " + first.row + ": " + first.errors.join("; ") : "";
      toast && toast(((error && error.message) || "The rules were not imported.") + rowMessage);
    } finally {
      setBulkBusy(false);
      if (input) input.value = "";
    }
  };

  return (
    <div data-screen-label={title}>
      {!embedded && <Crumbs path={[{ label: "Dashboard" }, { label: "Health Rules" }]} />}
      <div className="page-head">
        <div>
          <h1 className="page-title">{title}</h1>
          <p className="page-sub">Manage validation and health rules for recipes, ingredients and allergens.</p>
        </div>
        <div className="comp-head-actions">
          <CompLoraaAssist context={addLabel.replace("Add ", "").toLowerCase()} onDraft={canEdit ? () => openWizard("add") : null} />
          {canEdit && wizardType === "nutrition" && (
            <>
              <input ref={bulkFileRef} type="file" accept=".csv,text/csv" style={{ display: "none" }} onChange={uploadRules} />
              <button className="btn secondary" disabled={bulkBusy} onClick={downloadTemplate}><Icon name="download" size={16} /> Download Template</button>
              <button className="btn secondary" disabled={bulkBusy} onClick={() => bulkFileRef.current && bulkFileRef.current.click()}>
                <Icon name={bulkBusy ? "loader" : "upload"} size={16} className={bulkBusy ? "spin" : ""} /> {bulkBusy ? "Importing…" : "Bulk Upload"}
              </button>
            </>
          )}
          {canEdit
            ? <button className="btn primary" onClick={() => openWizard("add")}><Icon name="plus" size={16} /> Add Rule</button>
            : <span className="comp-readonly"><Icon name="lock" size={13} /> View only</span>}
        </div>
      </div>

      <CompStatCards cards={[
        { label: "Total Rules", value: total, icon: "file-text", tone: "blue" },
        { label: "Active Rules", value: active, icon: "circle-check", tone: "green" },
        { label: "Disabled Rules", value: total - active, icon: "circle-slash", tone: "grey" },
        { label: "Health Tag linked", value: linked, icon: "link-2", tone: "amber" },
      ]} />

      <div className="card comp-card">
        <div className="comp-toolbar">
          <div className="search comp-search"><Icon name="search" size={15} /><input placeholder="Search health rule" value={q} onChange={(e) => setQ(e.target.value)} /></div>
          <select className="comp-filter-select" value={typeF} onChange={(e) => setTypeF(e.target.value)}>
            <option value="all">All types</option>
            <option value="Nutrition">Nutrition</option>
            <option value="Health Tag">Health Tag</option>
            <option value="Ingredient">Ingredient</option>
          </select>
        </div>
        <div className="comp-table-wrap">
          <table className="comp-table">
            <thead><tr>
              <th>Rule Name</th><th>Date Updated</th><th>Type</th><th>Status</th><th>Severity</th><th>Source</th><th>Linked Tags</th><th className="ta-r">Action</th>
            </tr></thead>
            <tbody>
              {filtered.map((r) => (
                <tr key={r.id} className="comp-hrow">
                  <td><div className="comp-name">{r.name} {r._isDefault && <span className="pill success" style={{ marginLeft: 6 }}>Default</span>}</div><div className="comp-desc">{r.desc}</div></td>
                  <td className="comp-muted">{r.updated}</td>
                  <td><CompTypeBadge type={r.type} /></td>
                  <td><CompStatusText status={r.status} /></td>
                  <td><CompSeverityText severity={r.severity} /></td>
                  <td><CompSourceBadge source={r.source} /></td>
                  <td><CompPillRail items={r.tags} tone="green" /></td>
                  <td className="ta-r"><CompKebab canEdit={canEdit} status={r.status} onToggle={(s) => { compSetStatus("rules", r.id, s).then(() => { reload(); toast && toast(`Rule ${s === "active" ? "enabled" : "disabled"}`); }).catch((e) => { reload(); toast && toast((e && e.message) || "Rule status could not be saved."); }); }} onEdit={r._isDefault ? null : () => openWizard("edit", r)} onView={() => openWizard("view", r)} /></td>
                </tr>
              ))}
              {filtered.length === 0 && <tr><td colSpan="8" className="comp-empty">No rules match your search.</td></tr>}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}
function typeForWizard(t) { return t === "Health Tag" ? "healthtag" : t === "Ingredient" ? "ingredient" : "nutrition"; }

function NutrientRulesPage({ embedded }) { return <CompRulesPage title="Nutrient Rules" addLabel="Add Nutrition Rule" wizardType="nutrition" embedded={embedded} />; }
function IngredientRulesPage({ embedded }) { return <CompRulesPage title="Ingredient Swap & Alternative Rules" addLabel="Add Ingredient Rule" wizardType="ingredient" embedded={embedded} />; }

/* ───────── Health Tag Rules ───────── */
function HealthTagRulesPage({ embedded }) {
  const { role, openCompliance } = useApp();
  const canEdit = canEditCompliance(role);
  const [data, setData] = useCoState(compLoad);
  const [q, setQ] = useCoState("");
  const tags = data.healthtags;
  const reload = () => setData(compLoad());
  const filtered = useCoMemo(() => tags.filter((t) => !q || t.tag.toLowerCase().includes(q.toLowerCase())), [tags, q]);
  const total = tags.length, active = tags.filter((t) => t.status === "active").length;
  const linkedConds = new Set(tags.flatMap((t) => t.conditions)).size;
  const openWizard = (mode, row) => openCompliance && openCompliance({ type: "healthtag", mode, row, onSaved: reload });

  return (
    <div data-screen-label="Health Tag Rules">
      {!embedded && <Crumbs path={[{ label: "Health Tag Rules" }, { label: "Dashboard" }]} />}
      <div className="page-head">
        <div>
          <h1 className="page-title">Health Tag Rules</h1>
          <p className="page-sub">Manage nutrition rules that link meals, recipes, and ingredients to health conditions.</p>
        </div>
        <div className="comp-head-actions">
          <CompLoraaAssist context="health tag rule" onDraft={canEdit ? () => openWizard("add") : null} />
          {canEdit
            ? <button className="btn primary" onClick={() => openWizard("add")}><Icon name="plus" size={16} /> Add Rule</button>
            : <span className="comp-readonly"><Icon name="lock" size={13} /> View only</span>}
        </div>
      </div>

      <CompStatCards cards={[
        { label: "Total health tags", value: total, icon: "file-text", tone: "blue" },
        { label: "Active tags", value: active, icon: "circle-check", tone: "green" },
        { label: "Disabled tags", value: total - active, icon: "circle-slash", tone: "grey" },
        { label: "Health condition linked", value: linkedConds, icon: "link-2", tone: "amber" },
      ]} />

      <div className="card comp-card">
        <div className="comp-toolbar">
          <div className="search comp-search"><Icon name="search" size={15} /><input placeholder="Search health tag" value={q} onChange={(e) => setQ(e.target.value)} /></div>
        </div>
        <div className="comp-table-wrap">
          <table className="comp-table">
            <thead><tr>
              <th>Health Tag</th><th>Date Updated</th><th>Linked Health Condition</th><th>Status</th><th>Severity</th><th>Recommended nutrition</th><th>Source</th><th className="ta-r">Action</th>
            </tr></thead>
            <tbody>
              {filtered.map((t) => (
                <tr key={t.id} className="comp-hrow">
                  <td><div className="comp-name">{t.tag}</div></td>
                  <td className="comp-muted">{t.updated}</td>
                  <td><CompPillRail items={t.conditions} tone="amber" /></td>
                  <td><CompStatusText status={t.status} /></td>
                  <td><CompSeverityText severity={t.severity} /></td>
                  <td><CompPillRail items={t.nutrients} tone="green" /></td>
                  <td><CompSourceBadge source={t.source} /></td>
                  <td className="ta-r"><CompKebab canEdit={canEdit} status={t.status} onToggle={(s) => { compSetStatus("healthtags", t.id, s); reload(); toast && toast(`Rule ${s === "active" ? "enabled" : "disabled"}`); }} onEdit={() => openWizard("edit", t)} onView={() => openWizard("view", t)} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        <div className="comp-pager">
          <button className="comp-pg"><Icon name="arrow-left" size={14} /> Previous</button>
          <span className="comp-pg-n on">1</span><span className="comp-pg-n">2</span><span className="comp-pg-n">3</span><span className="comp-pg-dots">…</span><span className="comp-pg-n">8</span><span className="comp-pg-n">9</span><span className="comp-pg-n">10</span>
          <button className="comp-pg">Next <Icon name="arrow-right" size={14} /></button>
        </div>
      </div>
    </div>
  );
}

/* ───────── Allergen Table ───────── */
function AllergenTablePage({ embedded }) {
  const { role, toast, openCompliance } = useApp();
  const canEdit = canEditCompliance(role);
  const [data, setData] = useCoState(compLoad);
  const [q, setQ] = useCoState("");
  const allergens = data.allergens;
  const reload = () => setData(compLoad());
  useCoEffect(() => {
    const refresh = () => reload();
    window.addEventListener("nutridms-compliance", refresh);
    compSyncRemote().then(refresh).catch(() => {});
    return () => window.removeEventListener("nutridms-compliance", refresh);
  }, []);
  const openWizard = (mode, row) => openCompliance && openCompliance({ type: "allergen", mode, row, onSaved: reload });
  const filtered = useCoMemo(() => allergens.filter((a) => !q || a.allergen.toLowerCase().includes(q.toLowerCase())), [allergens, q]);
  const total = allergens.length, active = allergens.filter((a) => a.status === "active").length;
  const linkedIng = allergens.reduce((n, a) => n + a.ingredients.length, 0);

  return (
    <div data-screen-label="Allergen Table">
      {!embedded && <Crumbs path={[{ label: "Dashboard" }, { label: "Allergen Table" }]} />}
      <div className="page-head">
        <div>
          <h1 className="page-title">Allergen Table</h1>
          <p className="page-sub">Track allergens linked to specific ingredients for safety purposes.</p>
        </div>
        <div className="comp-head-actions">
          {canEdit
            ? <button className="btn primary" onClick={() => openWizard("add")}><Icon name="plus" size={16} /> Add Allergen Rule</button>
            : <span className="comp-readonly"><Icon name="lock" size={13} /> View only</span>}
        </div>
      </div>

      <CompStatCards cards={[
        { label: "Total Allergens", value: total, icon: "triangle-alert", tone: "blue" },
        { label: "Active Rules", value: active, icon: "circle-check", tone: "green" },
        { label: "Disabled Rules", value: total - active, icon: "circle-slash", tone: "grey" },
        { label: "Linked ingredients", value: 200, icon: "link-2", tone: "amber" },
      ]} />

      <div className="card comp-card">
        <div className="comp-toolbar">
          <div className="search comp-search"><Icon name="search" size={15} /><input placeholder="Search allergen" value={q} onChange={(e) => setQ(e.target.value)} /></div>
        </div>
        <div className="comp-table-wrap">
          <table className="comp-table">
            <thead><tr>
              <th>Allergen</th><th>Source</th><th>Severity</th><th>Linked ingredients</th><th>Cross-contact warning</th><th>Status</th><th className="ta-r">Action</th>
            </tr></thead>
            <tbody>
              {filtered.map((a) => (
                <tr key={a.id} className="comp-hrow">
                  <td><div className="comp-name">{a.allergen}</div></td>
                  <td><CompSourceBadge source={a.source} /></td>
                  <td><span className={`pill ${a.severity === "Critical" ? "error" : "warning"}`}>{a.severity}</span></td>
                  <td><CompPillRail items={a.ingredients} tone="red" /></td>
                  <td className="comp-xcontact"><Icon name="triangle-alert" size={13} /> {a.note}</td>
                  <td><CompStatusText status={a.status} /></td>
                  <td className="ta-r"><CompKebab canEdit={canEdit} status={a.status} onToggle={(s) => { compSetStatus("allergens", a.id, s).then(() => { reload(); toast && toast(`Allergen rule ${s === "active" ? "enabled" : "disabled"}`); }).catch((e) => { reload(); toast && toast((e && e.message) || "Allergen rule status could not be saved."); }); }} onEdit={() => openWizard("edit", a)} onView={() => openWizard("view", a)} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

/* Searchable multi-select chips (rolling-pill hover on chips + options) */
function CompMultiSelect({ options, value, onChange, placeholder, disabled, single, searchPlaceholder, allowCreate, onCreate, onSearchChange }) {
  const [open, setOpen] = useCoState(false);
  const [q, setQ] = useCoState("");
  const ref = useCoRef(null);
  const selected = Array.isArray(value) ? value.map((v) => String(v)) : [];
  const optionValue = (option) => String(option && typeof option === "object" ? (option.value != null ? option.value : option.id) : option);
  const optionLabel = (option) => String(option && typeof option === "object" ? (option.label != null ? option.label : option.name) : option);
  const selectedLabel = (selectedValue) => {
    const option = options.find((candidate) => optionValue(candidate) === String(selectedValue));
    return option ? optionLabel(option) : String(selectedValue);
  };
  useCoEffect(() => {
    if (!open) return;
    const close = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, [open]);
  const toggle = (o) => {
    const option = optionValue(o);
    if (single) { onChange([option]); setOpen(false); return; }
    onChange(selected.includes(option) ? selected.filter((x) => x !== option) : [...selected, option]);
  };
  const list = options.filter((o) => optionLabel(o).toLowerCase().includes(q.toLowerCase()));
  const qTrim = q.trim();
  const canCreate = allowCreate && qTrim && !options.some((o) => optionLabel(o).toLowerCase() === qTrim.toLowerCase());
  const createTag = () => { if (!qTrim) return; if (onCreate) onCreate(qTrim); toggle(qTrim); setQ(""); };
  return (
    <div className={`comp-ms ${disabled ? "is-disabled" : ""}`} ref={ref}>
      <button type="button" className="comp-ms-trigger" disabled={disabled} onClick={() => setOpen((o) => !o)}>
        <span className={selected.length ? "" : "ph"}>{selected.length ? (single ? selectedLabel(selected[0]) : `${selected.length} selected`) : placeholder}</span>
        <Icon name="chevron-down" size={15} />
      </button>
      {open && !disabled && (
        <div className="comp-ms-menu">
          <div className="comp-ms-search"><input autoFocus placeholder={searchPlaceholder || "Search…"} value={q} onChange={(e) => { const next = e.target.value; setQ(next); if (onSearchChange) onSearchChange(next); }} /><Icon name="search" size={14} /></div>
          <div className="comp-ms-opts">
            {list.map((o) => {
              const option = optionValue(o);
              const isSelected = selected.includes(option);
              return (
              <button type="button" key={option} className={`comp-ms-opt rp ${isSelected ? "on" : ""}`} onClick={() => toggle(o)}>
                {!single && <span className="comp-ms-check">{isSelected && <Icon name="check" size={13} />}</span>}{optionLabel(o)}
              </button>
              );
            })}
            {list.length === 0 && !canCreate && <div className="comp-ms-empty">No matches</div>}
            {canCreate && (
              <button type="button" className="comp-ms-opt rp comp-ms-create" onClick={createTag}>
                <span className="comp-ms-check"><Icon name="plus" size={13} /></span>Create “{qTrim}”
              </button>
            )}
          </div>
        </div>
      )}
      {!single && selected.length > 0 && (
        <div className="comp-chips">
          {selected.map((v) => <span className="comp-chip rp" key={v}>{selectedLabel(v)}{!disabled && <button onClick={() => toggle(v)}><Icon name="x" size={12} /></button>}</span>)}
        </div>
      )}
    </div>
  );
}

/* Recipe Table, compliance status of recipes against active rules */
function ComplianceRecipeTablePage({ embedded }) {
  const { role, openRecipe } = useApp();
  const rows = (typeof RECIPES !== "undefined" ? RECIPES : []).slice(0, 12);
  return (
    <div data-screen-label="Recipe Table">
      {!embedded && <Crumbs path={[{ label: "Dashboard" }, { label: "Recipe Table" }]} />}
      <div className="page-head">
        <div>
          <h1 className="page-title">Recipe Table</h1>
          <p className="page-sub">Recipes checked against active compliance &amp; health rules.</p>
        </div>
      </div>
      <div className="card comp-card">
        <div className="comp-table-wrap">
          <table className="comp-table">
            <thead><tr><th>Recipe</th><th>Cuisine</th><th>Flags</th><th>Status</th><th className="ta-r">Action</th></tr></thead>
            <tbody>
              {rows.map((r) => {
                const flags = (typeof complianceCheck === "function") ? complianceCheck((typeof compRecipeItem === "function") ? compRecipeItem(r) : { name: r.name, ingredients: r.ingredients || [] }, "recipe") : [];
                return (
                  <tr key={r.id}>
                    <td><div className="comp-name">{r.name}</div></td>
                    <td className="comp-muted">{r.cuisine}</td>
                    <td>{flags.length ? <span className="pill warning">{flags.length} flag{flags.length > 1 ? "s" : ""}</span> : <span className="pill success">Clear</span>}</td>
                    <td><CompStatusText status={["pending-review", "draft"].includes(r.status) ? "inactive" : "active"} /></td>
                    <td className="ta-r"><button className="comp-kebab-btn" onClick={() => openRecipe && openRecipe(r)} title="Open"><Icon name="external-link" size={15} /></button></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

/* ───────── Health Conditions ─────────
   Editable source of truth for the conditions referenced by Health Tag rules. */
function compNutrShort(n) { return String(n).replace(/\s*\(.*\)\s*$/, ""); }

function HealthConditionsPage({ embedded }) {
  const { role, toast } = useApp();
  const canEdit = canEditCompliance(role);
  const [data, setData] = useCoState(compLoad);
  const [q, setQ] = useCoState("");
  const [cat, setCat] = useCoState("All");
  const [modal, setModal] = useCoState(null); // {mode, row}
  const conditions = data.conditions || [];
  const tags = data.healthtags || [];
  const reload = () => setData(compLoad());
  useCoEffect(() => {
    const refresh = () => reload();
    window.addEventListener("nutridms-compliance", refresh);
    compSyncRemote().then(refresh).catch(() => {});
    return () => window.removeEventListener("nutridms-compliance", refresh);
  }, []);
  const linkCount = (name) => tags.filter((t) => (t.conditions || []).includes(name)).length;

  const filtered = useCoMemo(() => conditions.filter((c) =>
    (!q || c.name.toLowerCase().includes(q.toLowerCase()) || (c.description || "").toLowerCase().includes(q.toLowerCase()))
    && (cat === "All" || c.category === cat)
  ), [conditions, q, cat]);

  const total = conditions.length;
  const active = conditions.filter((c) => c.status === "active").length;
  const linkedTagRules = tags.filter((t) => (t.conditions || []).some((n) => conditions.find((c) => c.name === n))).length;

  return (
    <div data-screen-label="Health Conditions">
      {!embedded && <Crumbs path={[{ label: "Dashboard" }, { label: "Health Conditions" }]} />}
      <div className="page-head">
        <div>
          <h1 className="page-title">Health Conditions</h1>
          <p className="page-sub">Define the health conditions that nutrition &amp; health-tag rules are mapped to.</p>
        </div>
        <div className="comp-head-actions">
          {canEdit
            ? <button className="btn primary" onClick={() => setModal({ mode: "add", row: null })}><Icon name="plus" size={16} /> Add Health Condition</button>
            : <span className="comp-readonly"><Icon name="lock" size={13} /> View only</span>}
        </div>
      </div>

      <CompStatCards cards={[
        { label: "Total Conditions", value: total, icon: "heart-pulse", tone: "blue" },
        { label: "Active", value: active, icon: "circle-check", tone: "green" },
        { label: "Disabled", value: total - active, icon: "circle-slash", tone: "grey" },
        { label: "Linked health tags", value: linkedTagRules, icon: "tag", tone: "amber" },
      ]} />

      <div className="card comp-card">
        <div className="comp-toolbar">
          <div className="search comp-search"><Icon name="search" size={15} /><input placeholder="Search condition" value={q} onChange={(e) => setQ(e.target.value)} /></div>
          <select className="comp-filter-select" value={cat} onChange={(e) => setCat(e.target.value)}>
            <option value="All">All categories</option>
            {COMP_CONDITION_CATEGORIES.map((c) => <option key={c} value={c}>{c}</option>)}
          </select>
        </div>
        <div className="comp-table-wrap">
          <table className="comp-table">
            <thead><tr>
              <th>Condition</th><th>Category</th><th>Monitored nutrients</th><th>Linked health tags</th><th>Status</th><th className="ta-r">Action</th>
            </tr></thead>
            <tbody>
              {filtered.map((c) => (
                <tr key={c.id} className="comp-hrow">
                  <td>
                    <div className="comp-name">{c.name}</div>
                    {c.description && <div className="comp-cond-desc">{c.description}</div>}
                  </td>
                  <td><span className="comp-cat-badge">{c.category}</span></td>
                  <td><CompPillRail items={(c.nutrients || []).map(compNutrShort)} tone="green" /></td>
                  <td>{linkCount(c.name) ? <span className="pill success">{`${linkCount(c.name)} tag${linkCount(c.name) > 1 ? "s" : ""}`}</span> : <span className="comp-muted">—</span>}</td>
                  <td><CompStatusText status={c.status} /></td>
                  <td className="ta-r"><CompKebab canEdit={canEdit} status={c.status} onToggle={async (s) => { try { await compSetStatus("conditions", c.id, s); reload(); toast && toast(`Condition ${s === "active" ? "enabled" : "disabled"}`); } catch (error) { reload(); toast && toast(error.message || "Could not update health condition"); } }} onEdit={() => setModal({ mode: "edit", row: c })} onView={() => setModal({ mode: "view", row: c })} /></td>
                </tr>
              ))}
              {filtered.length === 0 && (
                <tr><td colSpan="6"><div className="comp-empty-row">No conditions match your search.</div></td></tr>
              )}
            </tbody>
          </table>
        </div>
      </div>

      {modal && <ConditionModal mode={modal.mode} row={modal.row} canEdit={canEdit} onClose={() => setModal(null)} onSaved={() => { reload(); setModal(null); toast && toast("Health condition saved"); }} />}
    </div>
  );
}

function ConditionModal({ mode, row, canEdit, onClose, onSaved }) {
  const readOnly = mode === "view" || !canEdit;
  const [name, setName] = useCoState(row ? row.name : "");
  const [category, setCategory] = useCoState(row ? row.category : COMP_CONDITION_CATEGORIES[0]);
  const [description, setDescription] = useCoState(row ? (row.description || "") : "");
  const [nutrients, setNutrients] = useCoState(row ? (row.nutrients || []).slice() : []);
  const [active, setActive] = useCoState(row ? row.status === "active" : true);
  const [err, setErr] = useCoState("");
  const [saving, setSaving] = useCoState(false);

  const save = async () => {
    if (!name.trim()) { setErr("Condition name is required"); return; }
    const id = row ? row.id : "hc-" + Date.now();
    setSaving(true);
    setErr("");
    try {
      await compSaveHealthCondition({
        id, __remote: !!(row && row.__remote), name: name.trim(), category,
        description: description.trim(), nutrients, severity: row ? row.severity : "medium",
        status: active ? "active" : "inactive",
      });
      onSaved();
    } catch (error) {
      setErr(error.message || "Could not save the health condition.");
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="cu-loraa-overlay comp-modal-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="comp-modal" role="dialog" aria-label="Health condition">
        <div className="comp-modal-head">
          <div>
            <h2>{mode === "edit" ? "Edit Health Condition" : mode === "view" ? "Health Condition" : "Add Health Condition"}</h2>
            <p>Define a condition that nutrition &amp; health-tag rules can be mapped to</p>
          </div>
          <button className="comp-modal-x" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        <div className="comp-modal-body">
          <label className="comp-fld"><span>Condition Name</span>
            <input value={name} disabled={readOnly || saving} placeholder="eg,. Hypertension, Diabetes" onChange={(e) => { setName(e.target.value); setErr(""); }} style={err ? { borderColor: "#FDA29B" } : null} />
            {err && <span className="comp-fld-err">{err}</span>}
          </label>
          <div className="comp-fld-row">
            <label className="comp-fld"><span>Category</span>
              <select value={category} disabled={readOnly} onChange={(e) => setCategory(e.target.value)}>{COMP_CONDITION_CATEGORIES.map((s) => <option key={s}>{s}</option>)}</select>
            </label>
          </div>
          <label className="comp-fld"><span>Description</span>
            <textarea rows="3" value={description} disabled={readOnly} placeholder="Brief clinical context and how meals should adapt for this condition" onChange={(e) => setDescription(e.target.value)} />
          </label>
          <label className="comp-fld"><span>Monitored nutrients <em className="comp-fld-opt">(optional)</em></span>
            <div className="comp-nutgrid">
              {COMP_NUTRIENTS.map((n) => {
                const on = nutrients.includes(n);
                return (
                  <button type="button" key={n} disabled={readOnly}
                    className={`comp-nutchip ${on ? "on" : ""}`}
                    onClick={() => setNutrients((cur) => cur.includes(n) ? cur.filter((x) => x !== n) : [...cur, n])}>
                    <span className="comp-nutchip-box">{on && <Icon name="check" size={12} />}</span>
                    {compNutrShort(n)}
                  </button>
                );
              })}
            </div>
          </label>
          {!readOnly && (
            <div className="comp-activate">
              <div><strong>Make this condition available?</strong><span>Active conditions can be linked from Health Tag &amp; nutrition rules</span></div>
              <button type="button" className={`la-toggle ${active ? "on" : ""}`} onClick={() => setActive((a) => !a)}><span className="la-knob" /></button>
            </div>
          )}
        </div>
        <div className="comp-modal-foot">
          <button className="btn secondary" onClick={onClose}>{readOnly ? "Close" : "Cancel"}</button>
          {!readOnly && <button className="btn primary" disabled={saving} onClick={save}>{saving ? "Saving…" : "Save Health Condition"}</button>}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  NutrientRulesPage, IngredientRulesPage, HealthTagRulesPage, AllergenTablePage,
  HealthConditionsPage, ComplianceRecipeTablePage, CompMultiSelect, CompTypeBadge, CompSourceBadge,
  CompSeverityText, CompStatusText, CompStatCards, CompKebab, CompLoraaAssist,
});
