// curate.jsx — in-portal product curation admin.
// Hidden behind #curate (or the Tweaks "Curate products" button). Lets you mark
// each product Exact / Also / Hide per bus, overriding the auto heuristic.
// Saves to localStorage immediately; Export downloads the map as JSON to bake in.

const { useState, useMemo } = React;

const STATUS_OPTS = [
  { id: 'auto',  label: 'Auto',  hint: 'Use the automatic rule' },
  { id: 'exact', label: 'Exact', hint: 'Bus-specific match (shown up top)' },
  { id: 'also',  label: 'Also',  hint: 'Universal / also-compatible' },
  { id: 'hide',  label: 'Hide',  hint: 'Never show for this bus' },
];

function CuratePanel({ onClose, onChange }) {
  const realBuses = useMemo(() => window.BUSES.filter(b => !b.comingSoon), []);
  const [busId, setBusId] = useState(realBuses[0].id);
  const [q, setQ] = useState('');
  const [cat, setCat] = useState('all');
  const [, force] = useState(0);
  const rerender = () => { force(x => x + 1); onChange && onChange(); };

  const bus = window.BUSES.find(b => b.id === busId);

  // Candidate products for this bus: anything currently tagged to it, plus
  // anything universal (so you can demote/hide universals per bus too).
  const candidates = useMemo(() => {
    return window.PRODUCTS.filter(p =>
      (p.buses || []).includes(busId) || window.isUniversalProduct(p)
    );
  }, [busId]);

  const cats = useMemo(() => {
    const s = new Set();
    candidates.forEach(p => (p.categories || []).forEach(c => s.add(c)));
    return ['all', ...[...s]];
  }, [candidates]);

  const visible = candidates.filter(p => {
    if (cat !== 'all' && !(p.categories || []).includes(cat)) return false;
    if (q && !(`${p.name} ${p.sku}`.toLowerCase().includes(q.toLowerCase()))) return false;
    return true;
  });

  const setStatus = (sku, status) => {
    window.CURATION.buses[busId] = window.CURATION.buses[busId] || { exact: [], also: [], hide: [] };
    const m = window.CURATION.buses[busId];
    ['exact', 'also', 'hide'].forEach(k => { m[k] = (m[k] || []).filter(s => s !== sku); });
    // also clear any global-universal membership when explicitly set here
    if (status !== 'auto') {
      window.CURATION.universal = (window.CURATION.universal || []).filter(s => s !== sku);
    }
    if (status === 'exact') m.exact.push(sku);
    else if (status === 'also') m.also.push(sku);
    else if (status === 'hide') m.hide.push(sku);
    window.saveCuration();
    rerender();
  };

  // Count per-bus exact selections for the chips
  const exactCount = (bid) => {
    const m = (window.CURATION.buses && window.CURATION.buses[bid]) || {};
    return (m.exact || []).length;
  };

  const effective = (sku) => window.curationStatus(sku, busId);
  const autoGuess = (p) => window.isUniversalProduct(p, busId) ? 'also' : 'exact';

  const resetBus = () => {
    if (!confirm(`Clear all curation for the ${bus.short}? This reverts to the automatic rule.`)) return;
    delete window.CURATION.buses[busId];
    window.saveCuration();
    rerender();
  };

  const exportJSON = () => {
    const blob = new Blob([JSON.stringify(window.CURATION, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = 'safebus-curation.json';
    document.body.appendChild(a); a.click();
    setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); }, 100);
  };

  const importJSON = (e) => {
    const file = e.target.files && e.target.files[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => {
      try {
        const parsed = JSON.parse(reader.result);
        window.CURATION = parsed;
        if (!window.CURATION.buses) window.CURATION.buses = {};
        if (!window.CURATION.universal) window.CURATION.universal = [];
        window.saveCuration();
        rerender();
      } catch (err) { alert('Could not read that file: ' + err.message); }
    };
    reader.readAsText(file);
  };

  // Totals for the header
  const totals = useMemo(() => {
    let exact = 0, also = 0, hide = 0;
    Object.values(window.CURATION.buses || {}).forEach(m => {
      exact += (m.exact || []).length; also += (m.also || []).length; hide += (m.hide || []).length;
    });
    return { exact, also, hide };
  }, [force]);

  return (
    <div className="curate">
      <div className="curate__bar">
        <div className="curate__brand">
          <span className="curate__dot"></span>
          Curate products
          <span className="curate__hint">Admin · changes save automatically</span>
        </div>
        <div className="curate__bar-actions">
          <label className="curate__btn curate__btn--ghost">
            Import
            <input type="file" accept="application/json" onChange={importJSON} hidden />
          </label>
          <button className="curate__btn curate__btn--ghost" onClick={exportJSON}>Export JSON</button>
          <button className="curate__btn curate__btn--primary" onClick={onClose}>Done</button>
        </div>
      </div>

      <div className="curate__buses">
        {realBuses.map(b => (
          <button
            key={b.id}
            className={"curate__bus " + (b.id === busId ? "is-active" : "")}
            onClick={() => setBusId(b.id)}
          >
            {b.short}
            {exactCount(b.id) > 0 && <span className="curate__bus-count">{exactCount(b.id)}</span>}
          </button>
        ))}
      </div>

      <div className="curate__toolbar">
        <input
          className="curate__search"
          placeholder={`Search ${bus.short} products…`}
          value={q}
          onChange={e => setQ(e.target.value)}
        />
        <div className="curate__cats">
          {cats.map(c => (
            <button
              key={c}
              className={"curate__cat " + (c === cat ? "is-active" : "")}
              onClick={() => setCat(c)}
            >
              {c === 'all' ? 'All' : (window.CATEGORIES.find(x => x.id === c) || { label: c }).label}
            </button>
          ))}
        </div>
        <div className="curate__count-note">{visible.length} products</div>
        <button className="curate__reset" onClick={resetBus}>Reset {bus.short}</button>
      </div>

      <div className="curate__list">
        {visible.map(p => {
          const eff = effective(p.sku);
          const guess = autoGuess(p);
          const hero = p.photos && p.photos[0];
          return (
            <div key={p.sku} className={"curate__row " + (eff === 'hide' ? "is-hidden" : "")}>
              <div className="curate__thumb" style={{ backgroundImage: hero ? `url(${hero})` : 'none' }}>
                {!hero && <span>{p.sku}</span>}
              </div>
              <div className="curate__meta">
                <div className="curate__name">{p.name}</div>
                <div className="curate__sub">
                  <span className="curate__sku">{p.sku}</span>
                  {(p.categories || []).map(c => (
                    <span key={c} className="curate__tag">{(window.CATEGORIES.find(x => x.id === c) || { label: c }).label}</span>
                  ))}
                </div>
              </div>
              <div className="curate__seg">
                {STATUS_OPTS.map(o => {
                  const active = eff === o.id || (o.id === 'auto' && eff === 'auto');
                  const isAutoShowingGuess = o.id === 'auto' && eff === 'auto';
                  return (
                    <button
                      key={o.id}
                      className={"curate__seg-btn " + (active ? "is-active " : "") + "curate__seg-btn--" + o.id}
                      title={o.hint}
                      onClick={() => setStatus(p.sku, o.id)}
                    >
                      {o.label}
                      {isAutoShowingGuess && <span className="curate__seg-guess">{guess}</span>}
                    </button>
                  );
                })}
              </div>
            </div>
          );
        })}
        {visible.length === 0 && (
          <div className="curate__empty">No products match your filters for the {bus.short}.</div>
        )}
      </div>

      <div className="curate__footer">
        <span><strong>{totals.exact}</strong> exact · <strong>{totals.also}</strong> also · <strong>{totals.hide}</strong> hidden across all buses</span>
        <span className="curate__footer-hint">When you're happy, hit <strong>Export JSON</strong> and send it over to bake in permanently.</span>
      </div>
    </div>
  );
}

Object.assign(window, { CuratePanel });
