// studio-real.jsx — shared plumbing for the honest Studio.
//
// Two jobs:
//   1. useMyOutfits() — load the signed-in user's rows from the Supabase
//      `outfits` table once per screen, with loading/error state. RLS scopes
//      the query to them.
//   2. NotTracked / NotTrackedPage — the single empty state used everywhere a
//      metric has no data source yet, so every such screen reads the same as
//      the "Performance analytics · Not tracked yet" card on the dashboard.
//
// Nothing in the Studio should render a number that did not come from the
// user's own account. If a figure has no source, it gets a NotTracked panel.

const { useState: useStateSR, useEffect: useEffectSR, useMemo: useMemoSR } = React;

// ─── Data ───────────────────────────────────────────────────────────────────

// Loads the current user's saved outfits. Returns { outfits, loading, error,
// reload } — every Studio screen that shows real data uses this.
function useMyOutfits() {
  const session = window.useSession ? window.useSession() : null;
  const [outfits, setOutfits] = useStateSR([]);
  const [loading, setLoading] = useStateSR(true);
  const [error, setError] = useStateSR(null);

  const reload = async () => {
    setLoading(true);
    setError(null);
    const res = await window.MBOutfits.list();
    if (res.error) { setError(res.error); setOutfits([]); }
    else setOutfits(res.outfits || []);
    setLoading(false);
  };

  useEffectSR(() => {
    if (!session) { setOutfits([]); setLoading(false); return; }
    reload();
  }, [session && session.id]);

  return { outfits, loading, error, reload, session };
}

// Roll the items inside every saved outfit up into a product list. This is the
// one genuinely derivable "products" view: a product is real because the user
// placed it on a board.
function deriveProducts(outfits) {
  const map = new Map();
  (outfits || []).forEach(o => {
    const when = +new Date(o.created_at) || 0;
    (o.items || []).forEach(it => {
      const brand = (it.brand || '').trim();
      const name = (it.name || '').trim();
      if (!brand && !name) return;
      const key = brand.toLowerCase() + '|' + name.toLowerCase();
      const cur = map.get(key);
      if (cur) {
        cur.outfitCount += 1;
        cur.outfitTitles.push(o.title || 'Untitled outfit');
        cur.firstUsed = Math.min(cur.firstUsed, when);
        cur.lastUsed = Math.max(cur.lastUsed, when);
        // Keep the first image/price we saw; later boards may have dropped them.
        if (!cur.image && it.image) cur.image = it.image;
        if (cur.price == null && it.price != null && it.price !== '') {
          const money = MBMoney.split(it.price, it.sourceUrl, it.currency);
          cur.price = money.price; cur.currency = money.currency;
        }
        if (!cur.sourceUrl && it.sourceUrl) cur.sourceUrl = it.sourceUrl;
      } else {
        map.set(key, {
          key,
          brand: brand || '—',
          name: name || 'Untitled product',
          kind: it.kind || null,
          image: it.image || it.originalImage || null,
          // A row that hasn't been repaired yet still arrives as "599 SEK";
          // split it here so the table never shows currency-in-the-amount.
          ...MBMoney.split(it.price, it.sourceUrl, it.currency),
          store: it.store || '',
          sourceUrl: it.sourceUrl || null,
          outfitCount: 1,
          outfitTitles: [o.title || 'Untitled outfit'],
          firstUsed: when,
          lastUsed: when,
        });
      }
    });
  });
  return [...map.values()];
}

// Distinct brands across the user's saved outfits, most-used first.
function deriveBrands(products) {
  const map = new Map();
  products.forEach(p => {
    const cur = map.get(p.brand) || { brand: p.brand, products: 0, placements: 0 };
    cur.products += 1;
    cur.placements += p.outfitCount;
    map.set(p.brand, cur);
  });
  return [...map.values()].sort((a, b) => b.placements - a.placements || b.products - a.products);
}

function fmtDay(ts) {
  if (!ts) return '—';
  return new Date(ts).toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
}

// ─── Empty states ───────────────────────────────────────────────────────────

// The panel. `metrics` lists what will appear here once tracking exists.
// The "Not tracked yet" subtitle is the one phrase used everywhere, so the
// dashboard and every Studio screen read the same.
function NotTracked({ title = 'Performance analytics', body, metrics, action }) {
  return (
    <Card title={title} sub="Not tracked yet">
      <div style={{ fontSize: 13, color: '#5a5a54', lineHeight: 1.6, maxWidth: '68ch' }}>{body}</div>
      {metrics && metrics.length > 0 && (
        <div style={{ marginTop: 16, display: 'flex', flexWrap: 'wrap', gap: 7 }}>
          {metrics.map(m => (
            <span key={m} style={{
              padding: '6px 12px', borderRadius: 999, fontSize: 11.5,
              background: '#F2EFE7', border: '1px solid rgba(20,20,18,0.05)', color: '#5a5550',
            }}>{m}</span>
          ))}
        </div>
      )}
      {action && (
        <button onClick={action.onClick} style={{ ...linkBtn, marginTop: 16 }}>{action.label}</button>
      )}
    </Card>
  );
}

// A whole screen whose every metric is untracked: header + one panel.
function NotTrackedPage({ kicker, title, sub, panelTitle = 'What would appear here', body, metrics, action }) {
  return (
    <div>
      <StudioHeader kicker={kicker} title={title} sub={sub}/>
      <NotTracked title={panelTitle} body={body} metrics={metrics} action={action}/>
    </div>
  );
}

// Shared loading / error / signed-out chrome so every screen behaves alike.
function StudioLoading({ label = 'Loading your outfits…' }) {
  return <Card><div style={{ fontSize: 13, color: '#8a8580' }}>{label}</div></Card>;
}

function StudioError({ error, onRetry }) {
  return (
    <Card>
      <div style={{ fontSize: 13, color: '#a8331a', lineHeight: 1.5 }}>{error}</div>
      {onRetry && <button onClick={onRetry} style={{ ...linkBtn, marginTop: 10 }}>Try again →</button>}
    </Card>
  );
}

// Shown on real-data screens when the account has nothing saved yet.
function StudioEmpty({ title, body, go }) {
  return (
    <Card>
      <div style={{ padding: '28px 0', textAlign: 'center' }}>
        <div style={{ fontSize: 14, marginBottom: 6 }}>{title}</div>
        <div style={{ fontSize: 12.5, color: '#8a8580', marginBottom: 16 }}>{body}</div>
        {go && (
          <button onClick={() => go({ name: 'dashboard' })} style={{
            appearance: 'none', border: 'none', background: '#1a1a18', color: '#FAFAF7',
            fontSize: 11, padding: '10px 18px', letterSpacing: '0.14em',
            textTransform: 'uppercase', fontWeight: 500, borderRadius: 999,
            cursor: 'pointer', fontFamily: 'inherit',
          }}>Create an outfit</button>
        )}
      </div>
    </Card>
  );
}

Object.assign(window, {
  useMyOutfits, deriveProducts, deriveBrands, fmtDay,
  NotTracked, NotTrackedPage, StudioLoading, StudioError, StudioEmpty,
});
