/* NutriDMS, Meal Programs module (UI)
   Landing/dashboard · Program Builder (3 layouts) · Loraa validation ·
   Assignment engine · Review workflow · Distribution · Reporting.
   Loaded in index.html (root), so asset paths are root-relative.
   ════════════════════════════════════════════════════════════════════════ */
const { useState: mUseState, useEffect: mUseEffect, useMemo: mUseMemo, useRef: mUseRef } = React;

function MpLoraaMark({ size = 22 }) {
  return <span className="ci-loraa-mark" style={{ width: size, height: size, display: "inline-grid", placeItems: "center", borderRadius: "50%", overflow: "hidden" }}><img src="assets/loraa-logo.png" alt="Loraa" style={{ width: "100%", height: "100%", objectFit: "contain" }} /></span>;
}

// Re-render when programs / gating change
function useMpRerender() {
  const [, bump] = mUseState(0);
  mUseEffect(() => {
    const h = () => bump((n) => n + 1);
    window.addEventListener("nutridms-mealprograms", h);
    window.addEventListener("storage", h);
    return () => { window.removeEventListener("nutridms-mealprograms", h); window.removeEventListener("storage", h); };
  }, []);
}

function MpStatusPill({ status }) {
  const s = MP_STATUS[status] || { label: status, tone: "neutral" };
  return <span className={`pill ${s.tone}`} style={{ textTransform: "none", fontWeight: 700 }}>{s.label}</span>;
}

// Meal-program review workflow (PRD §14), dynamic timeline
const MP_WORKFLOW = [
  { k: "draft", t: "Draft", ic: "file-edit" },
  { k: "validation", t: "Loraa Validation", ic: "lightbulb" },
  { k: "assignments", t: "Assignment Generation", ic: "list-checks" },
  { k: "updates", t: "Contributor Updates", ic: "pencil" },
  { k: "review", t: "Reviewer Verification", ic: "clipboard-check" },
  { k: "approval", t: "Manager Approval", ic: "shield-check" },
  { k: "publish", t: "Publish", ic: "send" },
  { k: "distribute", t: "Distribution", ic: "share-2" },
];
function mpStepIdx(prog) {
  if (prog.status === "published") return MP_WORKFLOW.length - 1;
  if (typeof prog._wfStepIdx === "number") return Math.min(prog._wfStepIdx, MP_WORKFLOW.length - 1);
  return { draft: 0, validating: 1, review: 4, changes: 3, approved: 5, ready: 6 }[prog.status] || 0;
}

/* ═══════════════════════ Subscription gate ═══════════════════════ */
function MealProgramsGate() {
  const { role, setPage } = useApp();
  const meta = mpPlanMeta();
  const canEnable = mpCan(role, "configure");
  return (
    <div className="mp-lock">
      <div className="mp-lock-badge"><Icon name="utensils" size={28} /></div>
      <h1 style={{ fontFamily: "var(--serif)", fontSize: 27, margin: "0 0 8px", letterSpacing: "-.02em" }}>Meal Programs is {mpPlan() === "starter" ? "a paid feature" : "turned off"}</h1>
      <p style={{ color: "var(--gray-600)", fontSize: 14.5, lineHeight: 1.6, maxWidth: 460, margin: "0 auto 22px" }}>
        Build, validate, review, approve, and distribute enterprise meal programs at scale, with Loraa intelligence checking every plan against your compliance rules.
      </p>
      <div style={{ display: "inline-flex", gap: 10, flexWrap: "wrap", justifyContent: "center" }}>
        {mpPlan() === "starter" ? (
          <button className="btn primary" onClick={() => setPage("settings")}><Icon name="arrow-up-circle" size={16} /> Upgrade to Professional</button>
        ) : canEnable ? (
          <button className="btn primary" onClick={() => { mpSetEnabled(true); }}><Icon name="toggle-right" size={16} /> Enable Meal Programs</button>
        ) : (
          <div className="pill warning" style={{ padding: "9px 14px" }}><Icon name="lock" size={13} /> Ask an admin to enable this module</div>
        )}
        <button className="btn secondary" onClick={() => setPage("settings")}><Icon name="settings" size={16} /> Subscription & Features</button>
      </div>
      <div style={{ marginTop: 22, fontSize: 12.5, color: "var(--gray-400)" }}>Current plan: <strong style={{ color: "var(--gray-600)" }}>{meta.label}</strong> · Meal Programs: {meta.mp}</div>
    </div>
  );
}

/* ═══════════════════════ Landing / dashboard ═══════════════════════ */
function MealPrograms() {
  useMpRerender();
  const { role, setPage, toast } = useApp();
  if (!mpEnabled()) return <MealProgramsGate />;

  const list = mpLoad();
  const rep = mUseMemo(() => mpReport(list), [JSON.stringify(list)]);
  const [filter, setFilter] = mUseState(window.__mpFilter || "all");
  const [q, setQ] = mUseState("");
  mUseEffect(() => {
    const h = (e) => setFilter(e.detail || window.__mpFilter || "all");
    window.addEventListener("mp-filter", h);
    return () => window.removeEventListener("mp-filter", h);
  }, []);

  const canCreate = mpCan(role, "create");
  const filters = [
    { id: "all", label: "All", n: list.length },
    { id: "draft", label: "Drafts", n: list.filter((p) => p.status === "draft").length },
    { id: "validating", label: "Validating", n: list.filter((p) => p.status === "validating").length },
    { id: "review", label: "In Review", n: list.filter((p) => ["review", "changes"].includes(p.status)).length },
    { id: "published", label: "Published", n: list.filter((p) => p.status === "published").length },
  ];
  const shown = list.filter((p) => {
    if (filter === "review" && !["review", "changes"].includes(p.status)) return false;
    if (filter !== "all" && filter !== "review" && p.status !== filter) return false;
    if (q && !p.name.toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });

  const kpis = [
    { v: rep.created, l: "Programs created", ic: "layers", bg: "var(--green-50)", c: "var(--green-700)" },
    { v: rep.published, l: "Published", ic: "send", bg: "#E0F2FE", c: "#0369A1" },
    { v: rep.review, l: "Under review", ic: "clipboard-check", bg: "#FEF3C7", c: "#B45309" },
    { v: rep.assignments, l: "Assignments generated", ic: "list-checks", bg: "#F3ECFE", c: "#7A3DD6" },
    { v: rep.hoursSaved + "h", l: "Hours saved", ic: "timer", bg: "#DCFCE7", c: "#15803D" },
  ];

  const openProg = (p) => { window.__mpOpen = p.id; setPage("meal-program-detail"); };

  return (
    <div className="enterprise-meal-programs">
      <Crumbs path={[{ label: "Meal Programs" }]} />
      <div className="page-head">
        <div>
          <h1 className="page-title">Meal Programs</h1>
          <p className="page-sub">Create, validate, approve, and distribute enterprise meal programs.</p>
        </div>
        <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
          {canCreate && <button className="btn primary" onClick={() => { window.__mpOpen = null; setPage("meal-program-builder"); }}><Icon name="plus" size={16} /> New Program</button>}
          <button className="btn secondary" onClick={() => toast("Reports exported")}><Icon name="bar-chart-3" size={16} /> Reports</button>
        </div>
      </div>

      {/* Reporting KPIs */}
      <div className="mp-kpis">
        {kpis.map((k) => (
          <div key={k.l} className="mp-kpi">
            <div className="mp-kpi-ic" style={{ background: k.bg, color: k.c }}><Icon name={k.ic} size={18} /></div>
            <div className="mp-kpi-v">{k.v}</div>
            <div className="mp-kpi-l">{k.l}</div>
          </div>
        ))}
      </div>

      {/* filters + search */}
      <div className="mp-filters">
        {filters.map((f) => (
          <button key={f.id} className={`mp-filter ${filter === f.id ? "on" : ""}`} onClick={() => { setFilter(f.id); window.__mpFilter = f.id; }}>{f.label} <span className="n">{f.n}</span></button>
        ))}
        <div className="search" style={{ marginLeft: "auto", minWidth: 220 }}>
          <Icon name="search" size={16} />
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search programs…" />
        </div>
      </div>

      {shown.length === 0 ? (
        <div className="card pad" style={{ textAlign: "center", padding: 48, color: "var(--gray-500)" }}>
          <Icon name="utensils" size={28} style={{ opacity: .4 }} />
          <p style={{ marginTop: 10 }}>No programs here yet.</p>
        </div>
      ) : (
        <div className="mp-track">
          {shown.map((p) => <MpProgramCard key={p.id} prog={p} onOpen={() => openProg(p)} />)}
        </div>
      )}
    </div>
  );
}

function MpProgramCard({ prog, onOpen }) {
  const type = MP_TYPES.find((t) => t.id === prog.type) || MP_TYPES[0];
  const flags = mUseMemo(() => mpValidate(prog), [JSON.stringify(prog)]);
  const crit = flags.filter((f) => f.severity === "critical").length;
  const flagCls = crit ? "err" : flags.length ? "warn" : "ok";
  const flagTxt = crit ? `${crit} blocking` : flags.length ? `${flags.length} to review` : "Validated";
  return (
    <div className="mp-card" onClick={onOpen}>
      <div className="mp-card-top">
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <span className={`mp-card-type ${prog.type}`}><Icon name={type.icon} size={13} /> {type.label}</span>
          <span style={{ marginLeft: "auto" }}><MpStatusPill status={prog.status} /></span>
        </div>
        <div className="mp-card-name">{prog.name}</div>
        <div className="mp-card-desc">{prog.description}</div>
        <div className="mp-card-meta">
          <span className="mp-meta-chip"><Icon name="calendar-days" size={12} /> {prog.durationWeeks} wks</span>
          <span className="mp-meta-chip"><Icon name="users" size={12} /> {prog.population}</span>
          <span className={`mp-flagdot ${flagCls}`}><Icon name={crit ? "alert-triangle" : flags.length ? "alert-circle" : "shield-check"} size={12} /> {flagTxt}</span>
        </div>
      </div>
      <div className="mp-card-foot">
        <div className="avatar">{prog.owner.initials}</div>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 12.5, fontWeight: 700, color: "var(--gray-800)" }}>{prog.owner.name}</div>
          <div style={{ fontSize: 11, color: "var(--gray-400)" }}>Updated {prog.updated}</div>
        </div>
        <span className="mp-card-ver">{prog.version}</span>
      </div>
    </div>
  );
}

if (typeof window !== "undefined") Object.assign(window, { MealPrograms, MealProgramsGate, MpStatusPill, MpLoraaMark, MP_WORKFLOW, mpStepIdx });
