// screens-my-outfits.jsx — the signed-in user's saved outfits, loaded from the
// Supabase `outfits` table (see supabase/schema.sql).
//
// Row Level Security scopes the query to the current user, so this only ever
// shows rows that user owns — which is what makes the per-row Edit / Publish /
// Delete actions safe to render here: the list is the owner's list. Every
// action still goes through a call that re-checks ownership server-side
// (`user_id = auth.uid()` in the policy, or inside the SECURITY DEFINER
// publish/unpublish functions), so the UI is a convenience, never the thing
// standing between one account and another's rows.

const { useState: useStateMO, useEffect: useEffectMO } = React;

function MyOutfitsScreen({ go }) {
  const session = useSession();
  const [outfits, setOutfits] = useStateMO([]);
  const [loading, setLoading] = useStateMO(true);
  const [error, setError]     = useStateMO(null);
  // { id, action } while a row action is in flight — one at a time, so a
  // double-click can't fire two deletes.
  const [busy, setBusy] = useStateMO(null);
  const [status, setStatus] = useStateMO(null);

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

  useEffectMO(() => {
    if (!session) { setLoading(false); return; }
    load();
  }, [session && session.id]);

  const patchRow = (id, patch) =>
    setOutfits(prev => prev.map(o => (o.id === id ? { ...o, ...patch } : o)));

  const remove = async (id) => {
    setBusy({ id, action: 'delete' });
    setStatus(null); setError(null);
    const res = await MBOutfits.remove(id);
    setBusy(null);
    if (res.error) { setError(res.error); return; }
    // events cascades from outfits, so this takes the outfit's recorded
    // activity with it, and its public URL stops resolving.
    setOutfits(prev => prev.filter(o => o.id !== id));
    setStatus('Outfit deleted, along with its link and its recorded activity.');
  };

  const publish = async (outfit) => {
    setBusy({ id: outfit.id, action: 'publish' });
    setStatus(null); setError(null);
    const res = await MBOutfits.publish(outfit.id);
    setBusy(null);
    if (res.error) { setError(res.error); return; }
    patchRow(outfit.id, { published: true, slug: res.slug });
    setStatus('Published. Anyone with the link can see this outfit.');
  };

  const unpublish = async (outfit) => {
    setBusy({ id: outfit.id, action: 'unpublish' });
    setStatus(null); setError(null);
    const res = await MBOutfits.unpublish(outfit.id);
    setBusy(null);
    if (res.error) { setError(res.error); return; }
    // The slug is kept, so publishing again restores the same URL.
    patchRow(outfit.id, { published: false });
    setStatus('Unpublished. The public link no longer works.');
  };

  // ─── Signed out ───────────────────────────────────────────────────────────
  if (!session) {
    return (
      <Shell>
        <EmptyState
          title="Log in to see your outfits"
          body="Your saved outfits are tied to your account."
          action={{ label: 'Log in', onClick: () => go({ name: 'login' }) }}
          secondary={{ label: 'Create an account', onClick: () => go({ name: 'signup' }) }}
        />
      </Shell>
    );
  }

  return (
    <Shell>
      <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase', color: '#8a8580' }}>Your archive</div>
          <h1 style={{ margin: '10px 0 0', fontSize: 'clamp(30px, 4vw, 46px)', fontWeight: 400, letterSpacing: '-0.03em' }}>
            My <em style={{ fontFamily: "'Instrument Serif',serif", fontStyle: 'italic' }}>outfits</em>
          </h1>
          <p style={{ marginTop: 10, color: '#5a5a54', fontSize: 14 }}>
            Signed in as {session.email}
          </p>
        </div>
        <button onClick={() => go({ name: 'dashboard' })} style={{
          appearance: 'none', border: 'none', background: '#1a1a18', color: '#FAFAF7',
          fontSize: 11.5, padding: '11px 18px', letterSpacing: '0.14em',
          textTransform: 'uppercase', fontWeight: 500, borderRadius: 999, cursor: 'pointer',
          fontFamily: 'inherit',
        }}>New outfit</button>
      </div>

      {error && (
        <div style={{ marginTop: 24 }}>
          <FormBanner>{error}</FormBanner>
          <button onClick={load} style={{ ...btnGhost, marginTop: 4 }}>Try again</button>
        </div>
      )}

      {status && !error && (
        <div style={{ marginTop: 24 }}>
          <FormBanner kind="info">{status}</FormBanner>
        </div>
      )}

      {loading && (
        <div style={{ marginTop: 48, display: 'flex', alignItems: 'center', gap: 12, color: '#8a8580', fontSize: 13 }}>
          <Spinner/> Loading your outfits…
        </div>
      )}

      {!loading && !error && outfits.length === 0 && (
        <div style={{ marginTop: 40 }}>
          <EmptyState
            title="No saved outfits yet"
            body="Build a look in the outfit editor and hit Save outfit — it’ll show up here."
            action={{ label: 'Create your first outfit', onClick: () => go({ name: 'dashboard' }) }}
          />
        </div>
      )}

      {!loading && outfits.length > 0 && (
        <div style={{
          marginTop: 36, display: 'grid', gap: 22,
          gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))',
        }}>
          {outfits.map(o => (
            <SavedOutfitCard
              key={o.id}
              outfit={o}
              busy={busy && busy.id === o.id ? busy.action : null}
              disabled={!!busy && busy.id !== o.id}
              onOpen={() => go({ name: 'dashboard', savedId: o.id })}
              onPublish={() => publish(o)}
              onUnpublish={() => unpublish(o)}
              onDelete={() => remove(o.id)}
            />
          ))}
        </div>
      )}
    </Shell>
  );
}

// ─── Card ───────────────────────────────────────────────────────────────────
// The board is still the click target for opening an outfit; the owner actions
// sit below it and stop their own clicks so neither swallows the other.
function SavedOutfitCard({ outfit, onOpen, onPublish, onUnpublish, onDelete, busy, disabled }) {
  const [confirm, setConfirm] = useStateMO(false);
  const items = outfit.items || [];
  const when = outfit.created_at
    ? new Date(outfit.created_at).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
    : '';
  const locked = disabled || !!busy;

  return (
    <div data-outfit={outfit.id} style={{
      border: '1px solid rgba(20,20,18,0.08)', borderRadius: 14, overflow: 'hidden',
      background: '#fff', display: 'flex', flexDirection: 'column',
      opacity: disabled ? 0.55 : 1,
    }}>
      <div onClick={onOpen} title="Open in the editor" style={{ cursor: 'pointer', background: '#FAFAF7' }}>
        {items.length > 0
          ? <OutfitBoard outfit={{ items }}/>
          : <div style={{
              aspectRatio: '1 / 1', display: 'flex', alignItems: 'center', justifyContent: 'center',
              color: '#a8a39d', fontSize: 12, letterSpacing: '0.1em', textTransform: 'uppercase',
            }}>Empty board</div>}
      </div>

      <div style={{ padding: '14px 16px 16px', borderTop: '1px solid rgba(20,20,18,0.06)' }}>
        <div style={{
          fontFamily: "'Instrument Serif',serif", fontStyle: 'italic', fontSize: 19,
          letterSpacing: '-0.01em', lineHeight: 1.2,
        }}>{outfit.title || 'Untitled outfit'}</div>

        <div style={{ marginTop: 6, fontSize: 11.5, color: '#8a8580', display: 'flex', gap: 8, flexWrap: 'wrap' }}>
          <span>{items.length} {items.length === 1 ? 'piece' : 'pieces'}</span>
          {outfit.mood && <><span>·</span><span>{outfit.mood}</span></>}
          {when && <><span>·</span><span>{when}</span></>}
          {outfit.published
            ? <><span>·</span><span style={{ color: '#1a6b3a' }}>Published</span></>
            : <><span>·</span><span>Private</span></>}
        </div>

        {/* Live public URL for published outfits; a hint for the rest. */}
        <div style={{ marginTop: 12 }}>
          <PublicUrl published={outfit.published} slug={outfit.slug} compact/>
        </div>

        {confirm ? (
          <div style={{ marginTop: 14 }}>
            <div style={{ fontSize: 12, color: '#a8331a', lineHeight: 1.5 }}>
              Delete “{outfit.title || 'Untitled outfit'}” for good? This also removes its
              public link and everything recorded about how people used it.
            </div>
            <div style={{ marginTop: 10, display: 'flex', gap: 8 }}>
              <button onClick={onDelete} disabled={locked} style={{ ...pillSolid, background: '#a8331a', opacity: locked ? 0.6 : 1 }}>
                {busy === 'delete' ? 'Deleting…' : 'Delete for good'}
              </button>
              <button onClick={() => setConfirm(false)} disabled={locked} style={pillGhost}>Cancel</button>
            </div>
          </div>
        ) : (
          <div style={{ marginTop: 14, display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <button onClick={onOpen} disabled={locked} style={pillOutline}>Edit</button>

            {outfit.published ? (
              <button onClick={onUnpublish} disabled={locked} style={pillGhost}>
                {busy === 'unpublish' ? 'Unpublishing…' : 'Unpublish'}
              </button>
            ) : (
              <button onClick={onPublish} disabled={locked} style={pillGhost}>
                {busy === 'publish' ? 'Publishing…' : 'Publish'}
              </button>
            )}

            <button onClick={() => setConfirm(true)} disabled={locked} style={{ ...pillGhost, marginLeft: 'auto' }}>
              Delete
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

// ─── Small shared bits ──────────────────────────────────────────────────────
const pillBase = {
  appearance: 'none', fontSize: 10.5, letterSpacing: '0.14em',
  textTransform: 'uppercase', fontWeight: 500, borderRadius: 999,
  cursor: 'pointer', fontFamily: 'inherit',
};
const pillSolid   = { ...pillBase, border: 'none', background: '#1a1a18', color: '#fff', padding: '8px 14px' };
const pillOutline = { ...pillBase, border: '1px solid rgba(20,20,18,0.18)', background: 'transparent', color: '#1a1a18', padding: '8px 14px' };
const pillGhost   = { ...pillBase, border: 'none', background: 'transparent', color: '#8a8580', padding: '8px 6px' };

function Shell({ children }) {
  return (
    <div style={{ padding: '48px 40px 80px', maxWidth: 1240, marginInline: 'auto' }}>
      {children}
    </div>
  );
}

function EmptyState({ title, body, action, secondary }) {
  return (
    <div style={{
      padding: '56px 32px', textAlign: 'center', border: '1px dashed rgba(20,20,18,0.16)',
      borderRadius: 16, background: '#fff',
    }}>
      <h2 style={{ margin: 0, fontSize: 24, fontWeight: 400, letterSpacing: '-0.02em' }}>{title}</h2>
      <p style={{ marginTop: 10, color: '#5a5a54', fontSize: 14, lineHeight: 1.6 }}>{body}</p>
      <div style={{ marginTop: 22, display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap' }}>
        {action && (
          <button onClick={action.onClick} style={{
            appearance: 'none', border: 'none', background: '#1a1a18', color: '#FAFAF7',
            fontSize: 11.5, padding: '12px 20px', letterSpacing: '0.14em',
            textTransform: 'uppercase', fontWeight: 500, borderRadius: 999, cursor: 'pointer',
            fontFamily: 'inherit',
          }}>{action.label}</button>
        )}
        {secondary && (
          <button onClick={secondary.onClick} style={{
            appearance: 'none', border: '1px solid rgba(20,20,18,0.18)', background: 'transparent',
            color: '#1a1a18', fontSize: 11.5, padding: '12px 20px', letterSpacing: '0.14em',
            textTransform: 'uppercase', fontWeight: 500, borderRadius: 999, cursor: 'pointer',
            fontFamily: 'inherit',
          }}>{secondary.label}</button>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { MyOutfitsScreen, SavedOutfitCard });
