/* NutriDMS, Recipe Library (Figma redesign) */

function rlDate(iso) {
  const d = new Date(iso);
  if (isNaN(d)) return iso;
  return `${d.getDate()}- ${d.toLocaleDateString("en-GB", { month: "long" })}- ${d.getFullYear()}`;
}

function RecipesList() {
  const { openRecipe, setPage, role, toast } = useApp();
  const [view, setView] = React.useState("list");
  const [q, setQ] = React.useState("");
  const [statusOverride, setStatusOverride] = React.useState({});
  const [removed, setRemoved] = React.useState(() => new Set());
  const [menuFor, setMenuFor] = React.useState(null);
  const [advOpen, setAdvOpen] = React.useState(false);
  const [confirmDel, setConfirmDel] = React.useState(null);
  const [binTick, setBinTick] = React.useState(0);

  // filters (driven by the Advanced Filters modal)
  const [status, setStatus] = React.useState(() => { const s = window.__libInitialStatus; window.__libInitialStatus = null; return s || "all"; });
  const [cuisine, setCuisine] = React.useState("all");
  const [sort, setSort] = React.useState("recent");
  const [dateFilter, setDateFilter] = React.useState("");
  // draft (uncommitted) modal values
  const [dStatus, setDStatus] = React.useState("all");
  const [dCuisine, setDCuisine] = React.useState("all");
  const [dSort, setDSort] = React.useState("recent");
  const [dDate, setDDate] = React.useState("");

  React.useEffect(() => {
    const h = () => setBinTick((n) => n + 1);
    window.addEventListener("nutridms-bin", h);
    return () => window.removeEventListener("nutridms-bin", h);
  }, []);
  React.useEffect(() => {
    if (!menuFor) return;
    const close = () => setMenuFor(null);
    document.addEventListener("click", close);
    return () => document.removeEventListener("click", close);
  }, [menuFor]);
  const [, bumpDrafts] = React.useState(0);
  React.useEffect(() => {
    const h = () => bumpDrafts((n) => n + 1);
    window.addEventListener("nutridms-drafts", h);
    return () => window.removeEventListener("nutridms-drafts", h);
  }, []);

  const ALL = React.useMemo(() => {
    const binned = window.binnedIds ? window.binnedIds("recipe") : new Set();
    return RECIPES
      .filter((r) => ["approved", "published"].includes(r.status))
      .filter((r) => !removed.has(r.id) && !binned.has(r.id));
  }, [bumpDrafts, removed, statusOverride, binTick]);

  const filtered = React.useMemo(() => {
    let list = [...ALL];
    // The Library is the approved collection. Drafts and submitted items stay
    // in authoring / Nutrition Review until a reviewer approves them.
    if (q) list = list.filter((r) => r.name.toLowerCase().includes(q.toLowerCase()) || String(r.contributor && r.contributor.name || "").toLowerCase().includes(q.toLowerCase()));
    if (status !== "all") list = list.filter((r) => r.status === status);
    if (cuisine !== "all") list = list.filter((r) => r.cuisine === cuisine);
    if (dateFilter) list = list.filter((r) => r.submitted && r.submitted <= dateFilter);
    if (sort === "az") list.sort((a, b) => a.name.localeCompare(b.name));
    else if (sort === "za") list.sort((a, b) => b.name.localeCompare(a.name));
    else if (sort === "cal-hi") list.sort((a, b) => b.calories - a.calories);
    else if (sort === "cal-lo") list.sort((a, b) => a.calories - b.calories);
    else list.sort((a, b) => b.submitted.localeCompare(a.submitted));
    return list;
  }, [q, status, cuisine, sort, dateFilter, ALL]);

  const cuisines = React.useMemo(() => Array.from(new Set(ALL.map((r) => r.cuisine))).sort(), [ALL]);
  const activeFilters = (status !== "all" ? 1 : 0) + (cuisine !== "all" ? 1 : 0) + (dateFilter ? 1 : 0) + (sort !== "recent" ? 1 : 0);

  const isContributor = role === "media-contributor";
  const isCompliance = role === "compliance" || role === "super-admin";
  const canDelete = role === "admin" || role === "super-admin";

  const openAdv = () => { setDStatus(status); setDCuisine(cuisine); setDSort(sort); setDDate(dateFilter); setAdvOpen(true); };
  const applyAdv = () => { setStatus(dStatus); setCuisine(dCuisine); setSort(dSort); setDateFilter(dDate); setAdvOpen(false); };

  // ── Actions ──
  const setStatusFor = (ids, st, verb) => {
    setStatusOverride((m) => { const n = { ...m }; ids.forEach((id) => { n[id] = st; }); return n; });
    toast(`${verb} ${ids.length} recipe${ids.length === 1 ? "" : "s"}`);
  };
  const removeIds = (ids, verb) => {
    ids.forEach((id) => { if (String(id).startsWith("draft_") && window.deleteDraftItem) window.deleteDraftItem("recipe", id); });
    setRemoved((s) => { const n = new Set(s); ids.forEach((id) => n.add(id)); return n; });
    toast(`${verb} ${ids.length} recipe${ids.length === 1 ? "" : "s"}`);
  };
  const who = (window.currentUser ? (window.currentUser(role) || {}).name : null) || "You";
  const binIds = (ids) => {
    const map = {}; ALL.forEach((r) => { map[r.id] = r; });
    ids.forEach((id) => { if (map[id] && window.binAdd) window.binAdd("recipe", map[id], who); });
    // When the backend is connected, also delete server-side.
    if (window.RecipeSync && window.RecipeSync.live()) {
      ids.forEach((id) => { if (map[id] && map[id].__remote) window.RecipeSync.push(map[id], "delete"); });
    }
    toast(`Moved ${ids.length} recipe${ids.length === 1 ? "" : "s"} to Recycle Bin`);
  };

  const exportCsv = () => {
    const cols = ["Reference", "Name", "Cuisine", "Category", "Status", "Priority", "Contributor", "Calories", "Protein", "Carbs", "Fat", "Submitted"];
    const esc = (v) => `"${String(v == null ? "" : v).replace(/"/g, '""')}"`;
    const rows = filtered.map((r) => [
      (window.auditRef ? window.auditRef("recipe", r) : r.id), r.name, r.cuisine, r.category, r.status, r.priority,
      r.contributor && r.contributor.name, r.calories, r.protein, r.carbs, r.fat, r.submitted,
    ].map(esc).join(","));
    const csv = [cols.map(esc).join(","), ...rows].join("\n");
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `nutridms-recipes-${new Date().toISOString().slice(0, 10)}.csv`;
    document.body.appendChild(a); a.click(); a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1000);
    toast(`Exported ${filtered.length} recipe${filtered.length === 1 ? "" : "s"} to CSV`);
  };

  const canEditPub = window.canEditPublished ? window.canEditPublished(role) : canDelete;
  const rowMenu = (r) => {
    const items = [
      { ic: "eye", label: "View", fn: () => openRecipe(r) },
      { ic: "lock", label: "Approved record", locked: true, fn: () => toast("Approved recipes are managed through the governed review workflow.") },
    ].filter(Boolean);
    return items;
  };

  return (
    <div className="rl">
      <Crumbs path={[{ label: "Recipe Library" }]} />

      {/* Header */}
      <div className="rl-head">
        <div>
          <h1 className="rl-title">Recipe Library</h1>
          <p className="rl-sub">Approved recipes from your active organization</p>
        </div>
        <div className="rl-head-actions">
          <button className="btn secondary" onClick={exportCsv}><Icon name="download" size={16} /> Export Data</button>
          <button className="btn primary" onClick={() => setPage("upload")}><Icon name="plus" size={16} /> Create New Recipe</button>
        </div>
      </div>

      {/* Toolbar */}
      <div className="rl-toolbar">
        <div className="rl-search">
          <Icon name="search" size={18} />
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search recipe, contributor..." />
        </div>
        <div className="rl-tools">
          <div className="rl-viewtog">
            <button className={view === "grid" ? "on" : ""} onClick={() => setView("grid")} aria-label="Grid view"><Icon name="layout-grid" size={17} /></button>
            <button className={view === "list" ? "on" : ""} onClick={() => setView("list")} aria-label="List view"><Icon name="list" size={17} /></button>
          </div>
          <button className={`rl-advbtn ${activeFilters ? "on" : ""}`} onClick={openAdv}>
            <Icon name="sliders-horizontal" size={16} /> Advanced Filter{activeFilters ? ` · ${activeFilters}` : ""}
          </button>
        </div>
      </div>

      {/* Status filter tabs (pill-roll) */}
      <div className="tabs rl-tabs">
        {[
          { id: "all", label: "All recipes", count: ALL.length },
          { id: "approved", label: "Approved", count: ALL.filter((r) => r.status === "approved").length },
          { id: "published", label: "Published", count: ALL.filter((r) => r.status === "published").length },
        ].map((t) => (
          <button key={t.id} className={status === t.id ? "on" : ""} onClick={() => setStatus(t.id)}>
            {t.label}
            <span className="rl-tab-count" style={{ background: status === t.id ? "var(--green-100)" : "var(--gray-100)", color: status === t.id ? "var(--green-700)" : "var(--gray-600)" }}>{t.count}</span>
          </button>
        ))}
      </div>

      {/* Body */}
      {view === "grid" ? (
        <div className="rl-grid">
          {filtered.map((r) => <RecipeCard key={r.id} recipe={r} onOpen={openRecipe} />)}
          {filtered.length === 0 && <div className="empty" style={{ gridColumn: "1/-1" }}><div className="icon"><Icon name="search-x" size={24} /></div><h3>No recipes match your filters</h3><p>Try clearing the search or Advanced Filter.</p></div>}
        </div>
      ) : (
        <div className="rl-tablewrap lib-tablewrap">
          <table className="rl-table table lib-table" style={{ minWidth: 880 }}>
            <thead>
              <tr>
                <th>Recipe Name</th>
                <th>Cuisine</th>
                <th>Contributor</th>
                <th>Nutrition</th>
                <th>Status</th>
                <th>Priority</th>
                <th>Submitted on</th>
                <th className="rl-th-menu"></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map((r) => (
                <tr key={r.id} onClick={() => openRecipe(r)}>
                  <td>
                    <div className="rl-recipe">
                      <div className="rl-thumb" style={{ backgroundImage: `url("${r.cover}")` }} />
                      <div className="rl-recipe-tx">
                        <div className="rl-recipe-nm">{r.name}</div>
                        <div className="rl-recipe-meta">{r.category} · {r.duration} min · {r.servings} servings</div>
                      </div>
                    </div>
                  </td>
                  <td className="rl-cuisine">{r.cuisine}</td>
                  <td className="rl-contrib">{r.contributor.name}</td>
                  <td className="rl-nutr"><b>{r.calories} (kcal)</b> <span className="rl-nutr-more">+ 4 others</span></td>
                  <td><StatusPill status={r.status} item={r} kind="recipe" /></td>
                  <td><PriorityPill priority={r.priority} /></td>
                  <td className="rl-date">{rlDate(r.submitted)}</td>
                  <td className="rl-menu-cell" onClick={(e) => e.stopPropagation()}>
                    <button className="rl-menu-btn" aria-label="Row menu" onClick={(e) => { e.stopPropagation(); setMenuFor(menuFor === r.id ? null : r.id); }}><Icon name="more-horizontal" size={18} /></button>
                    {menuFor === r.id && (
                      <div className="rl-menu" onClick={(e) => e.stopPropagation()}>
                        {rowMenu(r).map((a, idx) => (
                          <button key={idx} className={`rl-menu-item ${a.danger ? "danger" : ""} ${a.locked ? "locked" : ""}`} onClick={() => { setMenuFor(null); a.fn(); }}>
                            <Icon name={a.ic} size={15} stroke={2.2} /> {a.label}
                          </button>
                        ))}
                      </div>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {filtered.length === 0 && (
            <div className="empty"><div className="icon"><Icon name="search-x" size={24} /></div><h3>No recipes match your filters</h3><p>Try clearing the search or Advanced Filter.</p></div>
          )}
        </div>
      )}

      {/* Advanced Filters modal */}
      {advOpen && (
        <div className="rl-modal-scrim" onClick={() => setAdvOpen(false)}>
          <div className="rl-modal" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true">
            <button className="rl-modal-x" onClick={() => setAdvOpen(false)} aria-label="Close"><Icon name="x" size={18} /></button>
            <h2 className="rl-modal-t">Advanced Filters</h2>
            <p className="rl-modal-sub">Filter recipes by these options</p>
            <div className="rl-modal-grid">
              <label className="rl-mfield">
                <span>Status</span>
                <select value={dStatus} onChange={(e) => setDStatus(e.target.value)}>
                  <option value="all">Select status</option>
                  <option value="published">Published</option>
                  <option value="rejected">Rejected</option>
                </select>
              </label>
              <label className="rl-mfield">
                <span>Cuisine Type</span>
                <select value={dCuisine} onChange={(e) => setDCuisine(e.target.value)}>
                  <option value="all">All Cuisines</option>
                  {cuisines.map((c) => <option key={c} value={c}>{c}</option>)}
                </select>
              </label>
              <label className="rl-mfield">
                <span>Filter by date</span>
                <input type="date" value={dDate} onChange={(e) => setDDate(e.target.value)} placeholder="Select submission date" />
              </label>
              <label className="rl-mfield">
                <span>Sort by</span>
                <select value={dSort} onChange={(e) => setDSort(e.target.value)}>
                  <option value="recent">Recently submitted</option>
                  <option value="az">A-Z order</option>
                  <option value="za">Z-A order</option>
                  <option value="cal-hi">Calories High to Low</option>
                  <option value="cal-lo">Calories Low to high</option>
                </select>
              </label>
            </div>
            <div className="rl-modal-foot">
              <button className="btn secondary" onClick={() => setAdvOpen(false)}>Cancel</button>
              <button className="btn primary" onClick={applyAdv}><Icon name="filter" size={15} /> Apply Filter</button>
            </div>
          </div>
        </div>
      )}

      {confirmDel && (
        <ConfirmDialog
          title={`Move ${confirmDel.ids.length} recipe${confirmDel.ids.length === 1 ? "" : "s"} to Recycle Bin?`}
          body={`Deleted items are kept in the Recycle Bin for ${window.BIN_RETENTION_DAYS || 90} days, then permanently removed. An Admin can restore or permanently delete them from Settings → Recycle Bin.`}
          confirmLabel="Move to Recycle Bin"
          tone="danger"
          icon="trash-2"
          onCancel={() => setConfirmDel(null)}
          onConfirm={() => { binIds(confirmDel.ids); setConfirmDel(null); }}
        />
      )}
    </div>
  );
}

function formatDate(iso) {
  const d = new Date(iso);
  return d.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" });
}

Object.assign(window, { RecipesList, formatDate });
