// Page 1 — Product list with inline editable quantities, plus a sticky right
// sidebar with the Submit Requisition button and per-category pending counts.
//
// Per-row UX:
//   • Type a quantity, blur the field or press Enter → auto-saves to localStorage.
//   • If MOQ > 1 the "actual" rounded value shows next to the input.
//   • Remove (×) clears the entry. Empty/0 also clears.
//   • Once submitted today, the row freezes and shows a "Sent" badge instead.
//
// Click on the product name (left side) to open the per-product detail page.
// The quantity input is intentionally OUTSIDE that click target.

const ProductListView = ({
  M,
  selectedBranch,
  onSelectBranch,
  orderedToday,
  pendingMap,
  onPendingChange,
  onOpenProduct,
  onSubmitAll,
}) => {
  const [search, setSearch] = React.useState('');
  const [topFilter, setTopFilter] = React.useState('');

  // run_date's AI prediction per product for the current branch. Empty object if
  // the bootstrap response didn't carry predictions (older server / no model run).
  const branchPredictions = (M.predictions_run_date && M.predictions_run_date[selectedBranch]) || {};

  const tops = React.useMemo(
    () => Array.from(new Set(M.products.map(p => p.topCategory))).sort(),
    [M.products]
  );

  const filtered = React.useMemo(() => {
    const q = search.trim().toLowerCase();
    return M.products.filter(p => {
      if (topFilter && p.topCategory !== topFilter) return false;
      if (!q) return true;
      return p.name.toLowerCase().includes(q)
        || p.lastCategory.toLowerCase().includes(q);
    });
  }, [M.products, search, topFilter]);

  const grouped = React.useMemo(() => {
    const g = {};
    filtered.forEach(p => {
      g[p.topCategory] = g[p.topCategory] || {};
      g[p.topCategory][p.lastCategory] = g[p.topCategory][p.lastCategory] || [];
      g[p.topCategory][p.lastCategory].push(p);
    });
    return g;
  }, [filtered]);

  // ---- Sidebar stats: pending count per top-category, only categories with > 0 ----
  const sidebarStats = React.useMemo(() => {
    const totalsByTop = {};
    M.products.forEach(p => {
      totalsByTop[p.topCategory] = (totalsByTop[p.topCategory] || 0) + 1;
    });
    const pendingByTop = {};
    M.products.forEach(p => {
      if ((pendingMap[p.name] || 0) > 0) {
        pendingByTop[p.topCategory] = (pendingByTop[p.topCategory] || 0) + 1;
      }
    });
    return Object.keys(pendingByTop)
      .map(top => ({ top, set: pendingByTop[top], total: totalsByTop[top] || 0 }))
      .sort((a, b) => a.top.localeCompare(b.top));
  }, [M.products, pendingMap]);

  const totalPending = sidebarStats.reduce((s, c) => s + c.set, 0);

  return (
    <main className="max-w-[1600px] mx-auto px-4 sm:px-6 py-5">
      <div className="grid grid-cols-1 lg:grid-cols-12 gap-5">
        {/* MAIN — filters + product list */}
        <div className="lg:col-span-8">
          {/* Filters */}
          <div className="bg-white border border-slate-200 rounded-lg p-4 mb-5">
            <div className="grid grid-cols-1 sm:grid-cols-3 gap-3 items-end">
              <div>
                <label className="block text-[11px] font-medium text-slate-500 uppercase tracking-wide mb-1">
                  Branch
                </label>
                <select
                  value={selectedBranch}
                  onChange={(e) => onSelectBranch(e.target.value)}
                  className="w-full px-3 py-2 text-sm bg-white border border-slate-200 rounded-md hover:border-slate-300 focus:outline-none focus:ring-2 focus:ring-red-500/20 focus:border-red-500 transition"
                >
                  {M.branches.map(b => (
                    <option key={b.name} value={b.name}>{b.name}</option>
                  ))}
                </select>
              </div>
              <div>
                <label className="block text-[11px] font-medium text-slate-500 uppercase tracking-wide mb-1">
                  Top Category
                </label>
                <select
                  value={topFilter}
                  onChange={(e) => setTopFilter(e.target.value)}
                  className="w-full px-3 py-2 text-sm bg-white border border-slate-200 rounded-md hover:border-slate-300 focus:outline-none focus:ring-2 focus:ring-red-500/20 focus:border-red-500 transition"
                >
                  <option value="">All categories</option>
                  {tops.map(t => <option key={t} value={t}>{t}</option>)}
                </select>
              </div>
              <div>
                <label className="block text-[11px] font-medium text-slate-500 uppercase tracking-wide mb-1">
                  Search
                </label>
                <input
                  type="text"
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                  placeholder="Search products…"
                  className="w-full px-3 py-2 text-sm bg-white border border-slate-200 rounded-md hover:border-slate-300 focus:outline-none focus:ring-2 focus:ring-red-500/20 focus:border-red-500 transition"
                />
              </div>
            </div>
          </div>

          {/* Summary */}
          <div className="flex items-center justify-between mb-3 text-xs text-slate-500">
            <span>
              Showing <span className="font-semibold text-slate-700 tabular-nums">{filtered.length}</span> products
              {topFilter && <> in <span className="font-medium text-slate-700">{topFilter}</span></>}
              <span> · branch </span>
              <span className="font-medium text-slate-700">{selectedBranch}</span>
            </span>
            {totalPending > 0 && (
              <span className="inline-flex items-center gap-1.5 text-amber-700 font-medium">
                {totalPending} pending
              </span>
            )}
          </div>

          {/* List */}
          {filtered.length === 0 ? (
            <div className="bg-white border border-slate-200 rounded-lg py-16 text-center">
              <p className="text-sm font-medium text-slate-900">No products match</p>
              <p className="text-xs text-slate-500 mt-1">Try clearing the search or category filter.</p>
            </div>
          ) : (
            <div className="space-y-5">
              {Object.entries(grouped).map(([top, lastsObj]) => (
                <div key={top} className="bg-white border border-slate-200 rounded-lg overflow-hidden">
                  <div className="px-5 py-3 border-b border-slate-100 bg-slate-50/50 flex items-center justify-between">
                    <h3 className="text-sm font-semibold text-slate-900">{top}</h3>
                    <span className="text-xs text-slate-400 tabular-nums">
                      {Object.values(lastsObj).reduce((s, arr) => s + arr.length, 0)} products
                    </span>
                  </div>
                  <div>
                    {Object.entries(lastsObj).map(([last, prods]) => (
                      <div key={last}>
                        <div className="px-5 py-2 bg-white text-[11px] font-medium uppercase tracking-wide text-slate-500 border-t border-slate-100">
                          {last}
                        </div>
                        {prods.map(p => (
                          <ProductRow
                            key={p.name}
                            product={p}
                            run_date={M.run_date}
                            branch={selectedBranch}
                            submitted={orderedToday.has(p.name)}
                            pendingQty={pendingMap[p.name] || 0}
                            aiPrediction={branchPredictions[p.name]}
                            onOpen={onOpenProduct}
                            onPendingChange={onPendingChange}
                          />
                        ))}
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* SIDEBAR — sticky submit + category counts */}
        <div className="lg:col-span-4">
          <div className="lg:sticky lg:top-24 space-y-4">
            {/* Submit panel */}
            <div className="bg-white border border-slate-200 rounded-lg p-4">
              <div className="text-[11px] font-medium text-slate-500 uppercase tracking-wide">
                Pending Requisition
              </div>
              <div className="mt-2 mb-3 flex items-baseline gap-2">
                <span className="text-3xl font-semibold tabular-nums text-slate-900">{totalPending}</span>
                <span className="text-sm text-slate-500">product{totalPending === 1 ? '' : 's'}</span>
              </div>
              <button
                onClick={onSubmitAll}
                disabled={totalPending === 0}
                className="w-full inline-flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-semibold text-white bg-red-600 hover:bg-red-700 disabled:bg-slate-200 disabled:text-slate-400 disabled:cursor-not-allowed rounded-md transition shadow-sm"
              >
                <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                  <path d="M2 7l3 3 7-7" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
                </svg>
                Submit Requisition
              </button>
              <p className="mt-2 text-[11px] text-slate-500 leading-snug">
                Quantities are submitted with MOQ rounding applied. Branch: <span className="font-medium text-slate-700">{selectedBranch}</span>.
              </p>
            </div>

            {/* Category breakdown */}
            <div className="bg-white border border-slate-200 rounded-lg overflow-hidden">
              <div className="px-4 py-3 border-b border-slate-100">
                <h4 className="text-sm font-semibold text-slate-900">By Top Category</h4>
                <p className="text-[11px] text-slate-500 mt-0.5">Only categories with at least one pending product.</p>
              </div>
              {sidebarStats.length === 0 ? (
                <div className="px-4 py-8 text-center text-xs text-slate-400">
                  Nothing pending yet. Set a quantity on any product to start.
                </div>
              ) : (
                <ul className="divide-y divide-slate-100">
                  {sidebarStats.map(({ top, set, total }) => {
                    const pct = total > 0 ? Math.round((set / total) * 100) : 0;
                    return (
                      <li key={top} className="px-4 py-2.5">
                        <div className="flex items-center justify-between text-sm">
                          <span className="font-medium text-slate-700 truncate pr-2">{top}</span>
                          <span className="text-slate-500 tabular-nums shrink-0">
                            <span className="text-slate-900 font-semibold">{set}</span> of {total}
                          </span>
                        </div>
                        <div className="mt-1.5 h-1 bg-slate-100 rounded-full overflow-hidden">
                          <div className="h-full bg-red-600 transition-all" style={{ width: `${pct}%` }} />
                        </div>
                      </li>
                    );
                  })}
                </ul>
              )}
            </div>
          </div>
        </div>
      </div>
    </main>
  );
};

// Per-row component — local input state lets the user type freely; commit
// happens on blur or Enter. Empty/0 calls setPendingQty with 0 which removes
// the entry from localStorage.
const ProductRow = ({ product, run_date, branch, submitted, pendingQty, aiPrediction, onOpen, onPendingChange }) => {
  const moq = product.master?.minimumOrderQuantity || 0;
  const [val, setVal] = React.useState(String(pendingQty || ''));
  const hasPrediction = aiPrediction != null && Number.isFinite(aiPrediction);
  const predictedDisplay = hasPrediction ? Math.round(aiPrediction).toLocaleString() : null;
  // The AI prediction now comes from today's pipeline run, which forecasts
  // tomorrow's demand (invoicedate == run_date + 1). Tomorrow label is
  // shown both inline and in the tooltip so reps know the value's target day.
  const tomorrowLabel = React.useMemo(() => {
    if (!run_date) return '';
    const d = new Date(run_date);
    d.setDate(d.getDate() + 1);
    return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
  }, [run_date]);

  // Keep input in sync if parent state changes (Page 2 edit, submit-all clear, branch change).
  React.useEffect(() => { setVal(String(pendingQty || '')); }, [pendingQty, product.name, branch]);

  const num = Math.max(0, parseInt(val) || 0);
  const actual = window.roundUpToMoq ? window.roundUpToMoq(num, moq) : num;
  const dirty = num !== pendingQty;

  const commit = () => {
    if (!dirty) return;
    window.setPendingQty({ run_date, branch, product: product.name, quantity: num });
    onPendingChange();
  };
  const remove = () => {
    setVal('');
    if (pendingQty === 0) return;
    window.setPendingQty({ run_date, branch, product: product.name, quantity: 0 });
    onPendingChange();
  };

  return (
    <div className={`flex items-center justify-between gap-3 px-5 py-2.5 border-t border-slate-100 ${submitted ? 'bg-emerald-50/30' : 'hover:bg-slate-50/60'} transition`}>
      <button
        onClick={() => onOpen(product)}
        className="min-w-0 flex-1 text-left group"
      >
        <div className="text-sm font-medium text-slate-900 truncate group-hover:text-red-700 transition">
          {product.name}
        </div>
        <div className="text-xs text-slate-500 mt-0.5 truncate">
          {product.topCategory} <span className="text-slate-300 mx-1">·</span> {product.lastCategory}
          {moq > 1 && <> <span className="text-slate-300 mx-1">·</span> MOQ {moq}</>}
        </div>
      </button>
      <div className="flex items-center gap-2 shrink-0">
        {hasPrediction && (
          <span
            title={`Predicted demand for tomorrow${tomorrowLabel ? ` (${tomorrowLabel})` : ''}: ${predictedDisplay}`}
            className="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md text-[11px] font-medium bg-slate-50 text-slate-700 border border-slate-200 tabular-nums"
          >
            <span className="text-[10px] font-semibold tracking-wide text-slate-500">AI</span>
            {predictedDisplay}
          </span>
        )}
        {submitted ? (
          <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-[11px] font-medium bg-emerald-50 text-emerald-700 border border-emerald-200">
            <svg width="10" height="10" viewBox="0 0 12 12" fill="none">
              <path d="M3 6l2 2 4-4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            Sent
          </span>
        ) : (
          <>
            <input
              type="number"
              min="0"
              value={val}
              onChange={(e) => setVal(e.target.value)}
              onBlur={commit}
              onKeyDown={(e) => {
                if (e.key === 'Enter') { commit(); e.target.blur(); }
                if (e.key === 'Escape') { setVal(String(pendingQty || '')); e.target.blur(); }
              }}
              placeholder="0"
              className="w-20 px-2.5 py-1.5 text-sm bg-white border border-slate-200 rounded-md text-right tabular-nums focus:outline-none focus:ring-2 focus:ring-red-500/20 focus:border-red-500 transition"
              onClick={(e) => e.stopPropagation()}
            />
            <span className="text-xs text-slate-500 tabular-nums w-14 text-right">
              {moq > 1 && num > 0
                ? <>= <span className={`font-semibold ${actual !== num ? 'text-amber-700' : 'text-slate-700'}`}>{actual.toLocaleString()}</span></>
                : <span className="opacity-0">— </span>}
            </span>
            <button
              onClick={remove}
              disabled={pendingQty === 0 && num === 0}
              title="Remove from pending"
              className="p-1.5 text-slate-300 hover:text-red-600 hover:bg-red-50 rounded-md disabled:opacity-30 disabled:hover:bg-transparent disabled:hover:text-slate-300 transition"
            >
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                <path d="M3 3l8 8M11 3l-8 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
              </svg>
            </button>
          </>
        )}
      </div>
    </div>
  );
};

window.ProductListView = ProductListView;
