// mariusson — UserProfile drawer (account editor) + GlobalSearch bar
//
// UserProfile drawer
//   • Opens from the top-right avatar (replaces the bare role-switch popover).
//   • Lets the user edit display name, handle, region, bio, and switch role.
//   • Artists get extra fields (studio, accepts donations, website, email).
//   • Collectors get a small collection summary (count + a peek).
//
// GlobalSearch
//   • Top-center pill in the chrome. Click or press "/" to open.
//   • Searches artists, collectors (placeholder), and artworks across the
//     whole catalogue, with type-grouped results.
//   • Picking an artist opens their profile; picking a work drills into it.

// ─── UserProfile drawer ─────────────────────────────────────
function UserProfileDrawer({ account, role, savedCount, visible, onClose, onSave, onSignOut }) {
  const [draft, setDraft] = React.useState(() => ({
    name: account?.name || '',
    handle: account?.handle || (account?.name || '').toLowerCase().replace(/[^a-z]/g, ''),
    region: account?.region || 'France',
    bio: account?.bio || '',
    role: role || 'viewer',
    studio: account?.studio || '',
    website: account?.website || '',
    email: account?.email || '',
    acceptsDonations: account?.acceptsDonations ?? true,
  }));
  // Tabs default to "Activity" so users land on their stuff first.
  const [tab, setTab] = React.useState('activity');

  const update = (k, v) => setDraft((d) => ({ ...d, [k]: v }));
  const accent = draft.role === 'artist' ? BAU.red : draft.role === 'collector' ? BAU.yellow : BAU.ink;

  // Detect dirty (unsaved changes) so we can highlight Save when it matters.
  const dirty = (
    draft.name !== (account?.name || '') ||
    draft.handle !== (account?.handle || '') ||
    draft.region !== (account?.region || 'France') ||
    draft.bio !== (account?.bio || '') ||
    draft.role !== (role || 'viewer') ||
    draft.studio !== (account?.studio || '') ||
    draft.website !== (account?.website || '') ||
    draft.email !== (account?.email || '') ||
    draft.acceptsDonations !== (account?.acceptsDonations ?? true)
  );

  return (
    <div data-atlas-panel onClick={onClose} style={{
      position: 'absolute', inset: 0, zIndex: 50,
      background: visible ? 'rgba(14,14,12,0.42)' : 'rgba(14,14,12,0)',
      backdropFilter: visible ? 'blur(4px)' : 'blur(0px)',
      WebkitBackdropFilter: visible ? 'blur(4px)' : 'blur(0px)',
      transition: 'background 280ms var(--ease-out), backdrop-filter 280ms var(--ease-out), -webkit-backdrop-filter 280ms var(--ease-out)',
    }}>
      <div data-atlas-drawer onClick={(e) => e.stopPropagation()} style={{
        position: 'absolute', top: 0, right: 0, bottom: 0, width: 'min(520px, 94%)',
        background: BAU.paper, borderLeft: `1px solid ${BAU.ink}`,
        transform: visible ? 'translateX(0)' : 'translateX(100%)',
        transition: 'transform 380ms var(--ease-out)',
        display: 'flex', flexDirection: 'column', overflow: 'hidden',
      }}>
        {/* Bauhaus stripe */}
        <div style={{ display: 'flex', height: 8 }}>
          <div style={{ flex: 1, background: BAU.red }} />
          <div style={{ flex: 1, background: BAU.yellow }} />
          <div style={{ flex: 1, background: BAU.blue }} />
          <div style={{ flex: 1, background: BAU.ink }} />
        </div>

        {/* Header */}
        <div style={{ padding: '20px 28px 14px', borderBottom: `1px solid ${BAU.rule}`, display: 'flex', alignItems: 'center', gap: 16 }}>
          <div style={{
            width: 56, height: 56, background: accent,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 26,
            color: draft.role === 'collector' ? BAU.ink : BAU.paper,
            border: `1px solid ${BAU.ink}`,
          }}>{(draft.name || '?')[0].toUpperCase()}</div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase' }}>
              Your profile · {draft.role}
            </div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 26, fontStyle: 'italic', color: BAU.ink, marginTop: 2, lineHeight: 1.05 }}>
              {draft.name || 'Unnamed'}
            </div>
            <div style={{ fontFamily: 'var(--mono)', fontSize: 10, color: BAU.graphite, marginTop: 2 }}>
              @{draft.handle || 'handle'}
            </div>
          </div>
          <button onClick={onClose} title="Close" aria-label="Close profile" style={{
            background: 'transparent', border: `1px solid ${BAU.ink}`,
            width: 28, height: 28, padding: 0, cursor: 'pointer',
            fontFamily: 'var(--mono)', fontSize: 13, color: BAU.ink,
          }}>×</button>
        </div>

        {/* Tab strip — switches between the three high-level views.
            "Activity" is the user's stuff (works for artists, orders for
            collectors, saved-works for viewers). "Edit profile" is how
            others see them. "Account" is settings + sign out. */}
        <ProfileTabs role={draft.role} active={tab} onChange={setTab} />

        {/* Body */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '20px 28px 28px' }}>

          {tab === 'activity' && (
            <>
              {draft.role === 'artist' && account && (
                <>
                  <PortfolioIntro hasAny={!!(window.AN_UPLOADS?.listWorksForOwner(account.id) || []).length} />
                  <ArtistPortfolio ownerId={account.id} />
                  <StudioPointer
                    body="Briefs, sales receipts, and your payout method live in the Studio drawer — open it from the chrome bar." />
                </>
              )}
              {draft.role === 'collector' && account && (
                <>
                  <CollectorOwnedSummary ownerId={account.id} />
                  <StudioPointer
                    body="Owned works, receipts, payment methods, and conversations with artists are in the Studio drawer — open it from the chrome bar (the blue square)." />
                </>
              )}
              {draft.role === 'viewer' && (
                <ViewerActivityIntro savedCount={savedCount} />
              )}
            </>
          )}

          {tab === 'profile' && (
            <>
              <SectionIntro
                title="Public profile"
                description={draft.role === 'artist'
                  ? 'How collectors see you when they tap your name on a work.'
                  : draft.role === 'collector'
                  ? 'How artists see you when you commission, donate, or buy.'
                  : 'A name and handle so saves and posts are attributed to you.'}
              />

              <FieldGroup label="Display name" hint="Shown on every work and post you make.">
                <UPInput value={draft.name} onChange={(v) => update('name', v)} placeholder="Your name" />
              </FieldGroup>

              <FieldGroup label="Handle" hint="Like a username — letters, numbers, dots, underscores.">
                <UPInput value={draft.handle} onChange={(v) => update('handle', v.toLowerCase().replace(/[^a-z0-9._]/g, ''))} placeholder="handle" prefix="@" />
              </FieldGroup>

              <FieldGroup label="Region" hint="Used to tag your works on the atlas and in the wheel filter.">
                <UPSelect value={draft.region} onChange={(v) => update('region', v)} options={window.REGIONS || []} />
              </FieldGroup>

              <FieldGroup
                label="Bio"
                hint={draft.role === 'artist' ? 'One or two lines about your practice — appears on your artist page.'
                    : draft.role === 'collector' ? 'What you collect, what moves you. Visible to artists you commission.'
                    : 'A line about you. Optional.'}>
                <UPTextarea value={draft.bio} onChange={(v) => update('bio', v)}
                  placeholder={draft.role === 'artist' ? 'A line about your practice…' : draft.role === 'collector' ? 'What you collect, what moves you…' : 'A line about you…'} />
              </FieldGroup>

              {draft.role === 'artist' && (
                <>
                  <SectionIntro
                    title="Studio details"
                    description="Visible on your artist page. Helps collectors who want to reach you outside mariusson."
                    pad />

                  <FieldGroup label="Studio name" hint="The name printed on your certificates of authenticity.">
                    <UPInput value={draft.studio} onChange={(v) => update('studio', v)} placeholder="Studio Brutalia" />
                  </FieldGroup>
                  <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
                    <FieldGroup label="Website" hint="No https:// — just the domain.">
                      <UPInput value={draft.website} onChange={(v) => update('website', v)} placeholder="studio.art" />
                    </FieldGroup>
                    <FieldGroup label="Email" hint="For commission briefs and direct contact.">
                      <UPInput value={draft.email} onChange={(v) => update('email', v)} placeholder="studio@…" />
                    </FieldGroup>
                  </div>
                  <ToggleRow
                    label="Accept donations from collectors"
                    description="When on, collectors see a Donate button on your artist page in addition to Commission."
                    checked={!!draft.acceptsDonations}
                    onToggle={() => update('acceptsDonations', !draft.acceptsDonations)} />
                </>
              )}
            </>
          )}

          {tab === 'account' && (
            <>
              <SectionIntro
                title="Account & role"
                description="Switch how you use mariusson. You can move between roles any time — your saved works stay with you." />

              <FieldGroup label="Role" hint="Determines which CTAs and panels you see.">
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6 }}>
                  {[
                    { v: 'viewer', label: 'Viewer', sub: 'just looking', dot: BAU.ink },
                    { v: 'collector', label: 'Collector', sub: 'building a wall', dot: BAU.yellow },
                    { v: 'artist', label: 'Artist', sub: 'making work', dot: BAU.red },
                  ].map((r) => (
                    <button key={r.v} onClick={() => update('role', r.v)} style={{
                      background: draft.role === r.v ? BAU.ink : 'transparent',
                      color: draft.role === r.v ? BAU.paper : BAU.ink,
                      border: `1px solid ${BAU.ink}`,
                      padding: '12px 14px', cursor: 'pointer',
                      textAlign: 'left', display: 'flex', flexDirection: 'column', gap: 4,
                    }}>
                      <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                        <span style={{ width: 8, height: 8, borderRadius: '50%', background: r.dot, border: draft.role === r.v ? `1px solid ${BAU.paper}` : 'none' }} />
                        <span style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase' }}>{r.label}</span>
                      </span>
                      <span style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 12, opacity: 0.85 }}>{r.sub}</span>
                    </button>
                  ))}
                </div>
              </FieldGroup>

              <SectionIntro
                title="Sign out"
                description="Your works, orders, and saves stay safe. Sign back in any time with the same email."
                pad />
              {account && (
                <button onClick={onSignOut} style={{
                  background: 'transparent', border: `1px solid ${BAU.red}`,
                  padding: '10px 18px',
                  fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em',
                  textTransform: 'uppercase', cursor: 'pointer', color: BAU.red,
                  marginTop: 4,
                }}>Sign out of {account.email}</button>
              )}
            </>
          )}

        </div>

        {/* Footer — always visible, primary action highlighted only when
            there are unsaved changes. */}
        <div style={{
          padding: '14px 28px', borderTop: `1px solid ${BAU.ink}`,
          display: 'flex', gap: 10, alignItems: 'center',
          background: BAU.paper2,
        }}>
          {dirty && (
            <span style={{
              fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.14em',
              color: BAU.red, textTransform: 'uppercase',
              display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: BAU.red, animation: 'an-pulse 2.4s ease-in-out infinite' }} />
              Unsaved changes
            </span>
          )}
          <div style={{ flex: 1 }} />
          <button onClick={onClose} style={{
            background: 'transparent', border: `1px solid ${BAU.ink}`,
            padding: '8px 14px',
            fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em',
            textTransform: 'uppercase', cursor: 'pointer', color: BAU.ink,
          }}>Close</button>
          <button onClick={() => onSave(draft)}
            disabled={!dirty}
            title={dirty ? 'Save changes to your profile' : 'Nothing to save'}
            style={{
              background: dirty ? BAU.ink : BAU.graphite,
              color: BAU.paper, border: 'none',
              padding: '9px 18px',
              fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em',
              textTransform: 'uppercase', cursor: dirty ? 'pointer' : 'not-allowed',
              display: 'flex', alignItems: 'center', gap: 8,
              opacity: dirty ? 1 : 0.7,
            }}>
            <span style={{ width: 7, height: 7, borderRadius: '50%', background: accent }} />
            Save profile
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Profile drawer helpers ────────────────────────────────────────
function ProfileTabs({ role, active, onChange }) {
  // Tabs adapt to role: viewer doesn't have an Activity sub-feed beyond
  // its saved-list, but the tab is still useful as a landing surface.
  const tabs = [
    { id: 'activity', label: role === 'artist' ? 'Portfolio' : role === 'collector' ? 'Activity' : 'Saved', hint: role === 'artist' ? 'Your works' : role === 'collector' ? 'Your orders' : 'Your saves' },
    { id: 'profile',  label: 'Edit profile', hint: 'How others see you' },
    { id: 'account',  label: 'Account', hint: 'Role · sign out' },
  ];
  return (
    <div role="tablist" style={{
      display: 'flex',
      borderBottom: `1px solid ${BAU.ink}`,
      background: BAU.paper2,
    }}>
      {tabs.map((t) => {
        const sel = active === t.id;
        return (
          <button key={t.id}
            role="tab" aria-selected={sel}
            onClick={() => onChange(t.id)}
            title={t.hint}
            style={{
              flex: 1,
              background: sel ? BAU.paper : 'transparent',
              color: sel ? BAU.ink : BAU.graphite,
              border: 'none',
              borderRight: `1px solid ${BAU.rule}`,
              borderBottom: sel ? `2px solid ${BAU.ink}` : '2px solid transparent',
              padding: '12px 8px 10px',
              cursor: 'pointer',
              fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em',
              textTransform: 'uppercase',
              transition: 'background 0.15s var(--ease-out), color 0.15s var(--ease-out)',
            }}>
            {t.label}
          </button>
        );
      })}
    </div>
  );
}

function SectionIntro({ title, description, pad }) {
  return (
    <div style={{ marginTop: pad ? 28 : 0, marginBottom: 14 }}>
      <div style={{
        fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22,
        color: BAU.ink, lineHeight: 1.1, letterSpacing: '-0.01em',
      }}>{title}</div>
      {description && (
        <div style={{
          marginTop: 4,
          fontFamily: 'var(--sans)', fontSize: 12.5, color: BAU.graphite,
          lineHeight: 1.5,
        }}>{description}</div>
      )}
    </div>
  );
}

function FieldGroup({ label, hint, children }) {
  return (
    <div style={{ marginBottom: 18 }}>
      <div style={{
        fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.18em',
        color: BAU.graphite, textTransform: 'uppercase', marginBottom: 6,
      }}>{label}</div>
      {children}
      {hint && (
        <div style={{
          marginTop: 4,
          fontFamily: 'var(--sans)', fontSize: 11.5, color: BAU.graphite,
          fontStyle: 'italic',
        }}>{hint}</div>
      )}
    </div>
  );
}

function ToggleRow({ label, description, checked, onToggle }) {
  return (
    <button onClick={onToggle} type="button" style={{
      width: '100%', textAlign: 'left',
      display: 'flex', alignItems: 'flex-start', gap: 14,
      padding: '14px 16px',
      border: `1px solid ${BAU.rule}`,
      background: checked ? BAU.paper2 : BAU.paper,
      cursor: 'pointer', marginTop: 14,
      transition: 'background 0.2s var(--ease-out)',
    }}>
      <span style={{
        flexShrink: 0, marginTop: 2,
        width: 36, height: 18, borderRadius: 999, background: checked ? BAU.ink : BAU.paper2,
        border: `1px solid ${BAU.ink}`, position: 'relative',
        transition: 'background 0.2s var(--ease-out)',
      }}>
        <span style={{
          position: 'absolute', top: 1, left: checked ? 19 : 1,
          width: 14, height: 14, borderRadius: '50%',
          background: checked ? BAU.paper : BAU.ink,
          transition: 'left 0.2s var(--ease-out)',
        }} />
      </span>
      <div style={{ flex: 1 }}>
        <div style={{ fontFamily: 'var(--sans)', fontSize: 13, color: BAU.ink, fontWeight: 500 }}>{label}</div>
        {description && (
          <div style={{ marginTop: 2, fontFamily: 'var(--sans)', fontSize: 11.5, color: BAU.graphite, lineHeight: 1.5 }}>
            {description}
          </div>
        )}
      </div>
    </button>
  );
}

function PortfolioIntro({ hasAny }) {
  if (hasAny) {
    return (
      <SectionIntro
        title="Your portfolio"
        description="Drag rows to reorder — top of list is the first work in your carousel. Click Edit to change a price, retitle, or delete." />
    );
  }
  return (
    <div style={{
      padding: '20px 22px',
      border: `2px dashed ${BAU.ink}`,
      background: BAU.paper2,
      marginBottom: 18,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
        <span style={{ width: 10, height: 10, background: BAU.red }} />
        <span style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase' }}>
          Get started
        </span>
      </div>
      <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, color: BAU.ink, lineHeight: 1.2 }}>
        Consign your first work
      </div>
      <div style={{ marginTop: 8, fontFamily: 'var(--sans)', fontSize: 12.5, color: BAU.graphite, lineHeight: 1.5 }}>
        Press the <strong style={{ color: BAU.red }}>+ Consign</strong> button in the top bar.
        You'll pick an image, fill in a title and price, and the work shows up
        on the atlas as soon as you finish.
      </div>
    </div>
  );
}

function ActivityIntro({ hasAny }) {
  if (hasAny) {
    return (
      <SectionIntro
        title="Your activity"
        description="Every commission, donation, and purchase you've made on mariusson. Newest first." />
    );
  }
  return (
    <div style={{
      padding: '20px 22px',
      border: `2px dashed ${BAU.ink}`,
      background: BAU.paper2,
      marginBottom: 18,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
        <span style={{ width: 10, height: 10, borderRadius: '50%', background: BAU.yellow }} />
        <span style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase' }}>
          Get started
        </span>
      </div>
      <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, color: BAU.ink, lineHeight: 1.2 }}>
        Commission an artist or save a work
      </div>
      <div style={{ marginTop: 8, fontFamily: 'var(--sans)', fontSize: 12.5, color: BAU.graphite, lineHeight: 1.5 }}>
        Open any artwork on the atlas, click the artist's name, and you'll
        see the <strong>Commission similar →</strong> button. Donations to artists
        and purchases will land here too.
      </div>
    </div>
  );
}

// Quick summary of what the collector owns — points them to Studio for full details.
function CollectorOwnedSummary({ ownerId }) {
  const owned = (window.AN_STUDIO?.ownedWorksForBuyer(ownerId) || []);
  const orders = (window.AN_PAY?.listOrdersForBuyer(ownerId) || []);
  const purchaseCount = orders.filter((o) => o.type === 'purchase').length;
  const commissionCount = orders.filter((o) => o.type === 'commission').length;
  const donateCount = orders.filter((o) => o.type === 'donate').length;

  if (!owned.length && !orders.length) {
    return (
      <div style={{
        padding: '20px 22px', border: `2px dashed ${BAU.ink}`, background: BAU.paper2,
        marginBottom: 18,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
          <span style={{ width: 10, height: 10, borderRadius: '50%', background: BAU.yellow }} />
          <span style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase' }}>
            Get started
          </span>
        </div>
        <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, color: BAU.ink, lineHeight: 1.2 }}>
          Commission your first work
        </div>
        <div style={{ marginTop: 8, fontFamily: 'var(--sans)', fontSize: 12.5, color: BAU.graphite, lineHeight: 1.5 }}>
          Open any artwork on the atlas, click the artist's name, and use{' '}
          <strong style={{ color: BAU.ink }}>Commission similar →</strong>. Owned works show up here once you check out.
        </div>
      </div>
    );
  }

  return (
    <>
      <SectionIntro
        title="Your collection"
        description="Owned works (purchased + commissioned). Your saved works are separate — find them in Studio." />

      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)',
        border: `1px solid ${BAU.rule}`, marginBottom: 14,
      }}>
        {[
          { label: 'Owned',       count: owned.length,     accent: BAU.blue },
          { label: 'Commissions', count: commissionCount,  accent: BAU.red },
          { label: 'Donations',   count: donateCount,      accent: BAU.yellow },
        ].map((s, i, arr) => (
          <div key={s.label} style={{
            padding: '12px 14px',
            borderRight: i < arr.length - 1 ? `1px solid ${BAU.rule}` : 'none',
            position: 'relative',
          }}>
            <div style={{ position: 'absolute', top: 0, left: 0, width: 18, height: 3, background: s.accent }} />
            <div style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase' }}>{s.label}</div>
            <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 28, color: BAU.ink, marginTop: 2 }}>
              {String(s.count).padStart(2, '0')}
            </div>
          </div>
        ))}
      </div>

      {owned.length > 0 && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))', gap: 8 }}>
          {owned.slice(0, 6).map(({ order, workId, workTitle, workImage, status }) => (
            <div key={order.id} style={{
              border: `1px solid ${BAU.rule}`, background: BAU.paper, overflow: 'hidden',
            }}>
              <div style={{ aspectRatio: '1', background: BAU.paper2, overflow: 'hidden' }}>
                {workImage && <img src={workImage} alt={workTitle || ''} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />}
              </div>
              <div style={{ padding: '6px 8px' }}>
                <div style={{ fontFamily: 'var(--mono)', fontSize: 8.5, letterSpacing: '0.12em', color: order.type === 'commission' ? BAU.red : BAU.blue, textTransform: 'uppercase' }}>
                  ● {status}
                </div>
                <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 11.5, color: BAU.ink, lineHeight: 1.2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {workTitle || 'Untitled'}
                </div>
              </div>
            </div>
          ))}
        </div>
      )}
    </>
  );
}

// A nudge towards the Studio drawer — keeps the profile drawer focused
// on identity while pointing to where the heavy lifting lives.
function StudioPointer({ body }) {
  return (
    <div style={{
      marginTop: 22, padding: '14px 16px',
      border: `1px solid ${BAU.ink}`, background: BAU.paper2,
      display: 'flex', alignItems: 'center', gap: 12,
    }}>
      <span style={{
        width: 14, height: 14, background: BAU.blue, flexShrink: 0,
      }} />
      <div style={{ flex: 1, fontFamily: 'var(--sans)', fontSize: 12.5, color: BAU.ink, lineHeight: 1.4 }}>
        {body}
      </div>
    </div>
  );
}

function ViewerActivityIntro({ savedCount }) {
  return (
    <>
      <SectionIntro
        title="Saved works"
        description="Tiles you've saved show up here. Switch to Collector or Artist for richer profiles." />
      <div style={{
        display: 'flex', alignItems: 'baseline', gap: 14,
        padding: '14px 16px', border: `1px solid ${BAU.rule}`, background: BAU.paper2,
      }}>
        <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 38, lineHeight: 1, color: BAU.ink }}>
          {String(savedCount).padStart(2, '0')}
        </div>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em', color: BAU.graphite, textTransform: 'uppercase' }}>
          works · saved
        </div>
      </div>
    </>
  );
}

function FieldLabel({ children }) {
  return (
    <div style={{
      fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.18em',
      color: BAU.graphite, textTransform: 'uppercase', marginBottom: 6, marginTop: 12,
    }}>{children}</div>
  );
}
function SectionRule({ label }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 24, marginBottom: 4 }}>
      <span style={{
        fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.2em',
        color: BAU.ink, textTransform: 'uppercase',
      }}>{label}</span>
      <span style={{ flex: 1, height: 1, background: BAU.rule }} />
    </div>
  );
}
function UPInput({ value, onChange, placeholder, prefix }) {
  return (
    <div style={{ display: 'flex', alignItems: 'stretch', border: `1px solid ${BAU.ink}`, background: BAU.paper, marginBottom: 4 }}>
      {prefix && (
        <span style={{
          padding: '0 10px', display: 'flex', alignItems: 'center',
          fontFamily: 'var(--mono)', fontSize: 12, color: BAU.graphite,
          borderRight: `1px solid ${BAU.rule}`,
        }}>{prefix}</span>
      )}
      <input value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder}
        style={{
          flex: 1, padding: '10px 12px', border: 'none', outline: 'none',
          fontFamily: 'var(--sans)', fontSize: 13, color: BAU.ink, background: 'transparent',
        }} />
    </div>
  );
}
function UPTextarea({ value, onChange, placeholder }) {
  return (
    <textarea value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder}
      rows={3}
      style={{
        width: '100%', padding: '10px 12px',
        border: `1px solid ${BAU.ink}`, outline: 'none', resize: 'vertical',
        fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 14, color: BAU.ink,
        background: BAU.paper, marginBottom: 4,
      }} />
  );
}
function UPSelect({ value, onChange, options }) {
  return (
    <select value={value} onChange={(e) => onChange(e.target.value)}
      style={{
        width: '100%', padding: '10px 12px',
        border: `1px solid ${BAU.ink}`, outline: 'none',
        fontFamily: 'var(--sans)', fontSize: 13, color: BAU.ink,
        background: BAU.paper, marginBottom: 4, cursor: 'pointer',
        appearance: 'none', backgroundImage: `linear-gradient(45deg, transparent 50%, ${BAU.ink} 50%), linear-gradient(135deg, ${BAU.ink} 50%, transparent 50%)`,
        backgroundPosition: 'calc(100% - 18px) center, calc(100% - 12px) center',
        backgroundSize: '6px 6px',
        backgroundRepeat: 'no-repeat',
        paddingRight: 32,
      }}>
      {options.map((o) => <option key={o} value={o}>{o}</option>)}
    </select>
  );
}


// ─── Global Search ──────────────────────────────────────────
// A real inline input. Click to focus, type to search. Results drop down
// directly beneath the bar. No keyboard shortcuts, no modal overlay.
// Click anywhere outside the bar to close the dropdown.
function GlobalSearch({ catalogue, onPickWork, onPickArtist }) {
  const [q, setQ] = React.useState('');
  const [focused, setFocused] = React.useState(false);
  const wrapRef = React.useRef(null);

  // Close on outside click
  React.useEffect(() => {
    if (!focused) return;
    const onDocDown = (e) => {
      if (!wrapRef.current) return;
      if (!wrapRef.current.contains(e.target)) setFocused(false);
    };
    document.addEventListener('mousedown', onDocDown);
    return () => document.removeEventListener('mousedown', onDocDown);
  }, [focused]);

  // Build artist + (synthetic) collector indices once.
  const indices = React.useMemo(() => {
    const artistMap = new Map();
    catalogue.forEach((w) => {
      if (!artistMap.has(w.artist)) artistMap.set(w.artist, { name: w.artist, region: w.region, count: 0, latestYear: 0, sample: w });
      const e = artistMap.get(w.artist);
      e.count += 1;
      if (w.year > e.latestYear) { e.latestYear = w.year; e.sample = w; }
    });
    const artists = [...artistMap.values()];
    const collectors = artists.slice(0, 14).map((a, i) => ({
      name: ['Anouk', 'Mira', 'Theo', 'Iris', 'Niko', 'Ola', 'Saskia', 'Ren', 'Lior', 'Amaia', 'Bram', 'Esme', 'Tobias', 'Marit'][i] + ' ' + a.name.split(' ').slice(-1)[0],
      handle: a.name.toLowerCase().replace(/[^a-z]/g, '').slice(0, 8),
      region: a.region,
      collected: 3 + (i * 7) % 22,
    }));
    return { artists, collectors };
  }, [catalogue]);

  const results = React.useMemo(() => {
    const term = q.trim().toLowerCase();
    if (!term) return null;
    const m = (s) => s && s.toLowerCase().includes(term);
    const works = catalogue.filter((w) =>
      m(w.title) || m(w.artist) || m(w.region) || m(w.style) || m(w.theme) || m(w.method)
    ).slice(0, 6);
    const artists = indices.artists.filter((a) => m(a.name) || m(a.region)).slice(0, 5);
    const collectors = indices.collectors.filter((c) => m(c.name) || m(c.handle) || m(c.region)).slice(0, 4);
    return { works, artists, collectors };
  }, [q, catalogue, indices]);

  const showDropdown = focused && (q.trim().length > 0);
  const total = results ? results.works.length + results.artists.length + results.collectors.length : 0;

  const close = () => { setFocused(false); setQ(''); };
  const pickArtist = (a) => { close(); onPickArtist({ artistName: a.name, highlightWork: a.sample }); };
  const pickWork = (w) => { close(); onPickWork(w); };

  return (
    <div ref={wrapRef} data-atlas-panel style={{
      position: 'relative', pointerEvents: 'auto',
      width: '100%', maxWidth: 420,
    }}>
      {/* The bar */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        background: BAU.paper, border: `1px solid ${BAU.ink}`,
        borderRadius: 'var(--r-pill)',
        padding: '6px 14px',
        boxShadow: focused ? 'var(--shadow-soft)' : 'none',
        transition: 'box-shadow 0.2s var(--ease-out)',
      }}>
        <SearchIcon />
        <input
          value={q}
          onChange={(e) => setQ(e.target.value)}
          onFocus={() => setFocused(true)}
          placeholder="Search artists, works, regions, styles…"
          style={{
            flex: 1, border: 'none', outline: 'none', background: 'transparent',
            fontFamily: 'var(--sans)', fontSize: 13, color: BAU.ink,
            padding: '4px 0', minWidth: 0,
          }} />
        {q && (
          <button onClick={() => { setQ(''); }} title="Clear" style={{
            background: 'transparent', border: 'none', cursor: 'pointer',
            width: 18, height: 18, padding: 0,
            fontFamily: 'var(--mono)', fontSize: 14, color: BAU.graphite,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>×</button>
        )}
      </div>

      {/* Dropdown — sits directly below the bar */}
      {showDropdown && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 6px)', left: 0, right: 0,
          background: BAU.paper, border: `1px solid ${BAU.ink}`,
          borderRadius: 'var(--r-lg)',
          boxShadow: 'var(--shadow-softer)',
          maxHeight: '70vh', overflowY: 'auto',
          animation: 'an-fade-up 0.18s var(--ease-out)',
          zIndex: 5,
        }}>
          {/* Bauhaus stripe */}
          <div style={{ display: 'flex', height: 4 }}>
            <div style={{ flex: 1, background: BAU.red }} />
            <div style={{ flex: 1, background: BAU.yellow }} />
            <div style={{ flex: 1, background: BAU.blue }} />
          </div>

          {total === 0 && (
            <div style={{ padding: '28px 20px', textAlign: 'center' }}>
              <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 18, color: BAU.ink }}>
                Nothing under “{q}”.
              </div>
              <div style={{ fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.16em', color: BAU.graphite, textTransform: 'uppercase', marginTop: 6 }}>
                Try a region, style, or artist name
              </div>
            </div>
          )}

          {results && results.artists.length > 0 && (
            <ResultGroup label="Artists" count={results.artists.length} accent={BAU.red}>
              {results.artists.map((a) => (
                <ResultRow key={a.name}
                  onClick={() => pickArtist(a)}
                  leading={<span style={{ width: 28, height: 28, background: BAU.red, color: BAU.paper, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 13, border: `1px solid ${BAU.ink}` }}>{a.name[0]}</span>}
                  title={a.name}
                  sub={`${a.region} · ${a.count} ${a.count === 1 ? 'work' : 'works'} · active ${a.latestYear}`} />
              ))}
            </ResultGroup>
          )}

          {results && results.works.length > 0 && (
            <ResultGroup label="Works" count={results.works.length} accent={BAU.blue}>
              {results.works.map((w) => (
                <ResultRow key={w.id}
                  onClick={() => pickWork(w)}
                  leading={<MiniThumb work={w} />}
                  title={<span style={{ fontStyle: 'italic' }}>{w.title}</span>}
                  sub={`${w.artist} · ${w.year} · ${w.style} · ${w.region}`} />
              ))}
            </ResultGroup>
          )}

          {results && results.collectors.length > 0 && (
            <ResultGroup label="Collectors" count={results.collectors.length} accent={BAU.yellow}>
              {results.collectors.map((c) => (
                <ResultRow key={c.handle}
                  onClick={() => { /* placeholder — no collector profile yet */ }}
                  leading={<span style={{ width: 28, height: 28, background: BAU.yellow, color: BAU.ink, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 13, border: `1px solid ${BAU.ink}` }}>{c.name[0]}</span>}
                  title={c.name}
                  sub={`@${c.handle} · ${c.region} · ${c.collected} works`}
                  muted />
              ))}
            </ResultGroup>
          )}
        </div>
      )}
    </div>
  );
}

function SearchIcon() {
  return (
    <span style={{ width: 14, height: 14, position: 'relative', display: 'inline-block', flexShrink: 0 }}>
      <span style={{ position: 'absolute', top: 0, left: 0, width: 9, height: 9, border: `1.5px solid ${BAU.ink}`, borderRadius: '50%' }} />
      <span style={{ position: 'absolute', bottom: 0, right: 0, width: 6, height: 1.5, background: BAU.ink, transform: 'rotate(45deg)', transformOrigin: 'left center' }} />
    </span>
  );
}

function ResultGroup({ label, count, accent, children }) {
  if (count === 0) return null;
  return (
    <div>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '10px 20px 6px',
        fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.18em',
        color: BAU.ink, textTransform: 'uppercase',
      }}>
        <span style={{ width: 8, height: 8, background: accent }} />
        <span>{label}</span>
        <span style={{ color: BAU.graphite }}>· {count}</span>
      </div>
      <div>{children}</div>
    </div>
  );
}

function ResultRow({ onClick, leading, title, sub, muted }) {
  const [hover, setHover] = React.useState(false);
  return (
    <button onClick={onClick}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      style={{
        display: 'flex', alignItems: 'center', gap: 14,
        padding: '8px 20px', width: '100%',
        background: hover ? BAU.paper2 : 'transparent',
        border: 'none', borderTop: `1px solid ${BAU.rule}`,
        cursor: muted ? 'default' : 'pointer', textAlign: 'left',
        opacity: muted ? 0.7 : 1,
      }}>
      {leading}
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontFamily: 'var(--serif)', fontSize: 16, color: BAU.ink, lineHeight: 1.15, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{title}</div>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.12em', color: BAU.graphite, textTransform: 'uppercase', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{sub}</div>
      </div>
      <span style={{ fontFamily: 'var(--mono)', fontSize: 13, color: BAU.ink, opacity: hover ? 1 : 0.2, transition: 'opacity 0.15s var(--ease-out)' }}>↗</span>
    </button>
  );
}

function MiniThumb({ work }) {
  return (
    <div style={{ width: 38, height: 38, border: `1px solid ${BAU.ink}`, overflow: 'hidden', flexShrink: 0 }}>
      <ArtTile work={work} width={38} height={38} />
    </div>
  );
}

function Kbd({ children }) {
  return (
    <span style={{
      border: `1px solid ${BAU.rule}`, background: BAU.paper, padding: '1px 5px',
      fontFamily: 'var(--mono)', fontSize: 9, color: BAU.ink, letterSpacing: 0,
    }}>{children}</span>
  );
}

function SuggestStrip({ catalogue, artists, onPickArtist, onPickWork }) {
  const featuredArtists = artists.slice(0, 4);
  const featuredWorks = catalogue.slice(0, 4);
  return (
    <div style={{ padding: '14px 20px 18px' }}>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase', marginBottom: 8 }}>
        Suggested · artists
      </div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 16 }}>
        {featuredArtists.map((a) => (
          <button key={a.name} onClick={() => onPickArtist(a)} style={{
            background: BAU.paper, border: `1px solid ${BAU.ink}`,
            padding: '6px 10px', cursor: 'pointer',
            fontFamily: 'var(--sans)', fontSize: 12, color: BAU.ink,
            display: 'inline-flex', alignItems: 'center', gap: 6,
          }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: BAU.red }} />
            {a.name}
          </button>
        ))}
      </div>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase', marginBottom: 8 }}>
        Suggested · works
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
        {featuredWorks.map((w) => (
          <button key={w.id} onClick={() => onPickWork(w)} style={{
            background: BAU.paper, border: `1px solid ${BAU.ink}`, padding: 0, cursor: 'pointer',
            display: 'flex', flexDirection: 'column', gap: 0, textAlign: 'left',
          }}>
            <div style={{ width: '100%', aspectRatio: '1', overflow: 'hidden' }}>
              <ArtTile work={w} width={140} height={140} />
            </div>
            <div style={{ padding: '6px 8px' }}>
              <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 12, color: BAU.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{w.title}</div>
              <div style={{ fontFamily: 'var(--mono)', fontSize: 8.5, letterSpacing: '0.12em', color: BAU.graphite, textTransform: 'uppercase' }}>{w.artist}</div>
            </div>
          </button>
        ))}
      </div>
    </div>
  );
}

// ─── Portfolio header — emphatic since it's the top of the drawer now
function PortfolioHeader() {
  return (
    <div style={{
      display: 'flex', alignItems: 'baseline', gap: 10,
      paddingBottom: 10, marginBottom: 10,
      borderBottom: `1px solid ${BAU.ink}`,
    }}>
      <span style={{
        width: 8, height: 8, background: BAU.red, alignSelf: 'center',
      }} />
      <span style={{
        fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22,
        color: BAU.ink, letterSpacing: '-0.01em',
      }}>Your portfolio</span>
      <span style={{
        marginLeft: 'auto',
        fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.14em',
        color: BAU.graphite, textTransform: 'uppercase',
      }}>How collectors will see your work</span>
    </div>
  );
}

// ─── Artist portfolio (own works) ─────────────────────────────────
function ArtistPortfolio({ ownerId }) {
  const works = (window.useUserWorks ? window.useUserWorks() : [])
    .filter((w) => w.ownerId === ownerId)
    .sort((a, b) => (a.position ?? a.createdAt ?? 0) - (b.position ?? b.createdAt ?? 0));
  const [editingId, setEditingId] = React.useState(null);
  // Drag-and-drop state for the whole list
  const [dragId, setDragId] = React.useState(null);     // id of the row being dragged
  const [overId, setOverId] = React.useState(null);     // id of the row currently hovered over (drop target)

  if (!works.length) {
    return (
      <div style={{
        padding: '20px 16px', border: `1px dashed ${BAU.rule}`,
        fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 13,
        color: BAU.graphite, textAlign: 'center',
      }}>
        Nothing consigned yet. Press <span style={{ fontFamily: 'var(--mono)', fontStyle: 'normal', fontSize: 10, padding: '2px 6px', border: `1px solid ${BAU.ink}`, color: BAU.ink }}>+ Consign</span> in the chrome bar to add your first work.
      </div>
    );
  }

  const onRowDragStart = (id) => (e) => {
    setDragId(id);
    setOverId(null);
    try {
      e.dataTransfer.effectAllowed = 'move';
      e.dataTransfer.setData('text/plain', id);
    } catch {}
  };
  const onRowDragOver = (id) => (e) => {
    e.preventDefault();           // required so onDrop fires
    if (!dragId || dragId === id) return;
    setOverId(id);
    try { e.dataTransfer.dropEffect = 'move'; } catch {}
  };
  const onRowDragLeave = (id) => () => {
    if (overId === id) setOverId(null);
  };
  const onRowDrop = (id) => (e) => {
    e.preventDefault();
    const src = dragId || (e.dataTransfer && e.dataTransfer.getData('text/plain'));
    setDragId(null);
    setOverId(null);
    if (!src || src === id) return;
    window.AN_UPLOADS.reorderWork(src, id);
  };
  const onListDragEnd = () => { setDragId(null); setOverId(null); };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}
         onDragEnd={onListDragEnd}>
      <div style={{
        fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.16em',
        color: BAU.graphite, textTransform: 'uppercase', marginBottom: 8,
      }}>
        {works.length} work{works.length === 1 ? '' : 's'} · drag rows to reorder · or use ▲ ▼
      </div>
      {works.map((w, i) => (
        <PortfolioRow
          key={w.id}
          work={w}
          isFirst={i === 0}
          isLast={i === works.length - 1}
          editing={editingId === w.id}
          dragging={dragId === w.id}
          dropTarget={overId === w.id && dragId && dragId !== w.id}
          onToggleEdit={() => setEditingId((id) => id === w.id ? null : w.id)}
          onSaved={() => setEditingId(null)}
          onDragStart={onRowDragStart(w.id)}
          onDragOver={onRowDragOver(w.id)}
          onDragLeave={onRowDragLeave(w.id)}
          onDrop={onRowDrop(w.id)}
        />
      ))}
    </div>
  );
}

function PortfolioRow({
  work, isFirst, isLast, editing, dragging, dropTarget,
  onToggleEdit, onSaved,
  onDragStart, onDragOver, onDragLeave, onDrop,
}) {
  const move = (dir) => window.AN_UPLOADS.moveWork(work.id, dir);
  return (
    <div
      draggable
      onDragStart={onDragStart}
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
      style={{
        border: dropTarget ? `2px solid ${BAU.red}` : `1px solid ${BAU.rule}`,
        background: BAU.paper,
        marginBottom: 6,
        opacity: dragging ? 0.45 : 1,
        transition: 'opacity 0.15s var(--ease-out), border-color 0.15s var(--ease-out)',
      }}>
      <div style={{ display: 'flex', alignItems: 'stretch', gap: 0 }}>
        {/* Drag handle + ▲/▼ rail */}
        <div style={{
          width: 44, flexShrink: 0,
          display: 'flex', flexDirection: 'column',
          borderRight: `1px solid ${BAU.ink}`,
          background: BAU.paper2,
        }}>
          <button onClick={() => move(-1)} disabled={isFirst} title="Move up"
            style={orderBtnStyle(isFirst)}>▲</button>
          {/* Big visible drag-grip — cursor changes to grab/grabbing. The
              draggable attribute is on the whole row, but THIS surface is
              what hints "pick me up". */}
          <div title="Drag to reorder"
            style={{
              flexShrink: 0, flex: 1, minHeight: 36,
              borderTop: `1px solid ${BAU.rule}`, borderBottom: `1px solid ${BAU.rule}`,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              cursor: dragging ? 'grabbing' : 'grab',
              color: BAU.ink,
              fontFamily: 'var(--mono)', fontSize: 13, lineHeight: 1,
              letterSpacing: '0.06em',
              userSelect: 'none',
            }}>⋮⋮</div>
          <button onClick={() => move(1)} disabled={isLast} title="Move down"
            style={orderBtnStyle(isLast)}>▼</button>
        </div>
        <div style={{ width: 76, height: 76, flexShrink: 0, overflow: 'hidden', background: BAU.paper2 }}>
          <ArtTile work={work} width={76} height={76} />
        </div>
        <div style={{ flex: 1, padding: '10px 12px', minWidth: 0 }}>
          <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 15, color: BAU.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{work.title}</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 6, flexWrap: 'wrap' }}>
            <span style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em', color: BAU.graphite, textTransform: 'uppercase' }}>
              {work.region} · {work.style} · {work.year}
            </span>
            <ListingChip listing={work.listing} price={work.price} />
          </div>
        </div>
        <button onClick={onToggleEdit} style={{
          background: editing ? BAU.ink : 'transparent', color: editing ? BAU.paper : BAU.ink,
          border: 'none', borderLeft: `1px solid ${BAU.ink}`,
          padding: '0 16px', cursor: 'pointer',
          fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase',
        }}>{editing ? 'Close' : 'Edit'}</button>
      </div>
      {editing && (
        <PortfolioEditor work={work} onDone={onSaved} />
      )}
    </div>
  );
}

function orderBtnStyle(disabled) {
  return {
    width: 44, height: 24, padding: 0,
    background: disabled ? 'transparent' : BAU.paper,
    color: disabled ? BAU.graphite2 : BAU.ink,
    border: 'none', cursor: disabled ? 'not-allowed' : 'pointer',
    fontFamily: 'var(--mono)', fontSize: 11, lineHeight: 1,
    opacity: disabled ? 0.35 : 1,
    transition: 'background 0.15s var(--ease-out)',
  };
}

function ListingChip({ listing, price }) {
  if (listing === 'view-only') {
    return (
      <span style={{
        fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em',
        color: BAU.blue, textTransform: 'uppercase',
        padding: '2px 6px', border: `1px solid ${BAU.blue}`,
      }}>● View only</span>
    );
  }
  return (
    <span style={{
      fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em',
      color: BAU.ink, textTransform: 'uppercase',
      padding: '2px 6px', border: `1px solid ${BAU.ink}`,
    }}>● For sale · €{(price || 0).toLocaleString()}</span>
  );
}

function PortfolioEditor({ work, onDone }) {
  const [draft, setDraft] = React.useState({
    title: work.title || '',
    year: work.year || new Date().getFullYear(),
    region: work.region || 'France',
    style: work.style || 'Modernist',
    method: work.method || 'Oil',
    theme: work.theme || 'Memory',
    listing: work.listing || 'for-sale',
    price: work.price ?? 0,
    edition: work.edition || 'Unique',
  });
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState(null);

  const update = (k, v) => setDraft((d) => ({ ...d, [k]: v }));

  const save = () => {
    setBusy(true); setError(null);
    try {
      window.AN_UPLOADS.updateWork(work.id, {
        ...draft,
        year: Number(draft.year) || work.year,
        price: draft.listing === 'view-only' ? null : (Number(draft.price) || null),
      });
      onDone();
    } catch (e) { setError(e.message); }
    finally { setBusy(false); }
  };

  const remove = () => {
    if (!window.confirm(`Delete "${work.title}"? This can't be undone.`)) return;
    window.AN_UPLOADS.deleteWork(work.id);
    onDone();
  };

  const labelStyle = { fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.16em', color: BAU.graphite, textTransform: 'uppercase', marginBottom: 4 };
  const inputStyle = { width: '100%', boxSizing: 'border-box', border: `1px solid ${BAU.rule}`, background: BAU.paper, padding: '6px 8px', fontFamily: 'var(--sans)', fontSize: 12, color: BAU.ink, outline: 'none' };

  return (
    <div style={{ borderTop: `1px solid ${BAU.rule}`, padding: 14, background: BAU.paper2, display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div>
        <div style={labelStyle}>Title</div>
        <input style={inputStyle} value={draft.title} onChange={(e) => update('title', e.target.value)} />
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        <div>
          <div style={labelStyle}>Year</div>
          <input style={inputStyle} value={draft.year} onChange={(e) => update('year', e.target.value)} />
        </div>
        <div>
          <div style={labelStyle}>Edition</div>
          <input style={inputStyle} value={draft.edition} onChange={(e) => update('edition', e.target.value)} />
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        <div>
          <div style={labelStyle}>Region</div>
          <select style={inputStyle} value={draft.region} onChange={(e) => update('region', e.target.value)}>
            {(window.REGIONS || []).map((o) => <option key={o} value={o}>{o}</option>)}
          </select>
        </div>
        <div>
          <div style={labelStyle}>Style</div>
          <select style={inputStyle} value={draft.style} onChange={(e) => update('style', e.target.value)}>
            {(window.STYLES || []).map((o) => <option key={o} value={o}>{o}</option>)}
          </select>
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        <div>
          <div style={labelStyle}>Method</div>
          <select style={inputStyle} value={draft.method} onChange={(e) => update('method', e.target.value)}>
            {(window.METHODS || []).map((o) => <option key={o} value={o}>{o}</option>)}
          </select>
        </div>
        <div>
          <div style={labelStyle}>Theme</div>
          <select style={inputStyle} value={draft.theme} onChange={(e) => update('theme', e.target.value)}>
            {(window.THEMES || []).map((o) => <option key={o} value={o}>{o}</option>)}
          </select>
        </div>
      </div>

      <div>
        <div style={labelStyle}>Listing & visibility</div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', border: `1px solid ${BAU.ink}` }}>
          <button onClick={() => update('listing', 'for-sale')} style={{
            background: draft.listing === 'for-sale' ? BAU.ink : BAU.paper,
            color: draft.listing === 'for-sale' ? BAU.paper : BAU.ink,
            border: 'none', borderRight: `1px solid ${BAU.ink}`, padding: '8px 10px',
            fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.14em', textTransform: 'uppercase', cursor: 'pointer',
          }}>● For sale</button>
          <button onClick={() => update('listing', 'view-only')} style={{
            background: draft.listing === 'view-only' ? BAU.ink : BAU.paper,
            color: draft.listing === 'view-only' ? BAU.paper : BAU.ink,
            border: 'none', padding: '8px 10px',
            fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.14em', textTransform: 'uppercase', cursor: 'pointer',
          }}>○ View only</button>
        </div>
      </div>

      {draft.listing === 'for-sale' && (
        <div>
          <div style={labelStyle}>Price · EUR</div>
          <input type="number" style={inputStyle} value={draft.price} onChange={(e) => update('price', e.target.value)} />
        </div>
      )}

      {error && (
        <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.08em', color: BAU.red, padding: '6px 10px', border: `1px solid ${BAU.red}`, background: 'rgba(230,57,70,0.06)' }}>{error}</div>
      )}

      <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginTop: 4 }}>
        <button onClick={remove} style={{
          background: 'transparent', color: BAU.red, border: `1px solid ${BAU.red}`,
          padding: '8px 12px', fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.14em', textTransform: 'uppercase', cursor: 'pointer',
        }}>Delete work</button>
        <div style={{ flex: 1 }} />
        <button onClick={onDone} style={{
          background: 'transparent', color: BAU.ink, border: `1px solid ${BAU.ink}`,
          padding: '8px 12px', fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.14em', textTransform: 'uppercase', cursor: 'pointer',
        }}>Cancel</button>
        <button onClick={save} disabled={busy} style={{
          background: busy ? BAU.graphite : BAU.ink, color: BAU.paper, border: 'none',
          padding: '8px 14px', fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.14em', textTransform: 'uppercase', cursor: busy ? 'wait' : 'pointer',
        }}>{busy ? 'Saving…' : 'Save'}</button>
      </div>
    </div>
  );
}

// ─── Buyer activity (purchases, commissions, donations) ─────────────
function BuyerActivity({ ownerId }) {
  const all = (window.useOrders ? window.useOrders() : []).filter((o) => o.buyerId === ownerId);
  if (!all.length) {
    return (
      <div style={{
        padding: '20px 16px', border: `1px dashed ${BAU.rule}`,
        fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 13,
        color: BAU.graphite, textAlign: 'center',
      }}>
        No commissions or donations yet. Open an artist's profile to send a brief.
      </div>
    );
  }
  const totals = all.reduce((acc, o) => { acc[o.type] = (acc[o.type] || 0) + o.amount; return acc; }, {});
  const counts = all.reduce((acc, o) => { acc[o.type] = (acc[o.type] || 0) + 1; return acc; }, {});

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0, border: `1px solid ${BAU.rule}` }}>
        <ActivityStat label="Commissions" count={counts.commission || 0} total={totals.commission || 0} accent={BAU.red} />
        <ActivityStat label="Donations"   count={counts.donate     || 0} total={totals.donate     || 0} accent={BAU.yellow} />
        <ActivityStat label="Purchases"   count={counts.purchase   || 0} total={totals.purchase   || 0} accent={BAU.blue} last />
      </div>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 9.5, letterSpacing: '0.16em', color: BAU.graphite, textTransform: 'uppercase' }}>
        Recent · newest first
      </div>
      {all.map((o) => <OrderRow key={o.id} order={o} />)}
    </div>
  );
}

function ActivityStat({ label, count, total, accent, last }) {
  return (
    <div style={{ padding: '12px 14px', borderRight: last ? 'none' : `1px solid ${BAU.rule}`, position: 'relative' }}>
      <div style={{ position: 'absolute', top: 0, left: 0, width: 18, height: 3, background: accent }} />
      <div style={{ fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.18em', color: BAU.graphite, textTransform: 'uppercase' }}>{label}</div>
      <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 22, lineHeight: 1.05, color: BAU.ink, marginTop: 4 }}>{count}</div>
      <div style={{ fontFamily: 'var(--mono)', fontSize: 9.5, color: BAU.graphite }}>€{total.toLocaleString()}</div>
    </div>
  );
}

function OrderRow({ order }) {
  const date = new Date(order.createdAt).toLocaleDateString();
  return (
    <div style={{
      border: `1px solid ${BAU.rule}`, padding: '10px 12px',
      display: 'grid', gridTemplateColumns: '1fr auto', gap: 6, alignItems: 'center',
      background: BAU.paper,
    }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{
            fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.14em',
            color: order.type === 'donate' ? BAU.yellow : order.type === 'commission' ? BAU.red : BAU.blue,
            textTransform: 'uppercase',
          }}>● {order.type}</span>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 9.5, color: BAU.graphite }}>{date}</span>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 9, color: BAU.graphite-2 }}>· {order.id}</span>
        </div>
        <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 14, color: BAU.ink, marginTop: 4, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
          {order.workTitle ? <>{order.workTitle} · </> : null}{order.artistName}
        </div>
      </div>
      <div style={{
        fontFamily: 'var(--mono)', fontSize: 12, color: BAU.ink, textAlign: 'right',
      }}>
        €{order.amount.toLocaleString()}
        <div style={{ fontSize: 9, color: BAU.graphite, marginTop: 2 }}>{order.card?.brand} ····{order.card?.last4}</div>
      </div>
    </div>
  );
}

Object.assign(window, { UserProfileDrawer, GlobalSearch });
