// "Me" screen — identity card, eligibility stats, my tracks, my votes.
//
// Three logical regions:
//
//   1. Identity card — large avatar, name + role pill + ban/block
//      pills if either is set, Discord handle, playtime, identifier
//      (mono). Inline "Künstlerprofil bearbeiten" button flips into
//      the embedded ArtistProfileForm.
//
//   2. Eligibility grid — 4 MiniStat tiles showing what the player
//      CAN currently do (upload / vote / direct-accept / verified).
//
//   3. Two columns:
//        • Meine Tracks  — submissions this user uploaded, with a
//          play button that fires through useAudio() into the global
//          NowPlayingBar.
//        • Deine Stimmen — submissions this user voted on, with the
//          vote direction.

function ProfileScreen({ me, submissions, refresh }) {
  const audio = useAudioStatus();
  // Memoise the two derived lists. `myVotes` was O(n×m) (outer filter
  // over all submissions, inner .some() over the votes of each) — on
  // a 1000-track catalog with 10 votes each that's 10k comparisons
  // every parent render. With memo we only pay that cost when the
  // submissions array actually changes.
  const mine    = React.useMemo(
    () => submissions.filter(s => s.identifier === me.identifier),
    [submissions, me.identifier],
  );
  const myVotes = React.useMemo(
    () => submissions.filter(s => s.votes.some(v => v.identifier === me.identifier)),
    [submissions, me.identifier],
  );
  const [editingProfile, setEditingProfile] = React.useState(false);

  // "Zuletzt gehört" + "Meine Likes" come from /api/me/library —
  // both lists mirror what shows up on the ingame phone, so a play
  // or heart in either surface shows up in the other.
  const [library, setLibrary] = React.useState({ recent: [], likes: [] });
  React.useEffect(() => {
    let cancelled = false;
    Api.library()
      .then(out => { if (!cancelled) setLibrary(out); })
      .catch(() => {});
    return () => { cancelled = true; };
  }, []);

  // Settings-mode artist-profile form is reused for in-place edits.
  // After save we re-fetch /me and exit edit mode so the displayed
  // name + avatar update without a full page reload.
  if (editingProfile) {
    const handleSaved = async () => {
      if (refresh) await refresh();
      setEditingProfile(false);
    };
    return <ArtistProfileForm me={me} mode="settings" onSaved={handleSaved}/>;
  }

  const avatarUrl = me.artistProfile?.avatarUrl;

  return (
    <div style={{ padding: '32px 36px 140px', maxWidth: 1100, margin: '0 auto' }}>

      {/* Identity card */}
      <Glass radius={24} padding={28} style={{ marginBottom: 18 }} orb="var(--magenta)">
        <div style={{ display: 'flex', alignItems: 'center', gap: 22, flexWrap: 'wrap' }}>
          {avatarUrl ? (
            <div style={{
              width: 88, height: 88, borderRadius: '50%', flexShrink: 0,
              background: `url(${avatarUrl}) center/cover`,
              boxShadow: '0 6px 18px rgba(20,8,40,0.45)',
            }}/>
          ) : (
            <Avatar player={me} size={88}/>
          )}

          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6, flexWrap: 'wrap' }}>
              <h1 style={{ fontWeight: 800, fontSize: 32, lineHeight: 1.05, letterSpacing: '-0.02em', margin: 0 }}>
                {me.name}
              </h1>
              <RolePill player={me}/>
              {isBanned(me) && <StatusBadge color="var(--danger)" bg="rgba(255,110,138,0.18)" icon="x">Gebannt</StatusBadge>}
              {isBlocked(me) && <StatusBadge color="var(--danger)" bg="rgba(127,29,29,0.25)" icon="shield">Gesperrt</StatusBadge>}
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap', color: 'var(--fg-2)' }}>
              {me.discord && (
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 13 }}>
                  <ApIcon name="discord" size={14} color="var(--info)"/> @{me.discord}
                </span>
              )}
              <span style={{ color: 'var(--fg-4)' }}>·</span>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 13 }}>
                <ApIcon name="clock" size={13}/> {me.playtime}h Spielzeit
              </span>
              <span style={{ color: 'var(--fg-4)' }}>·</span>
              <IdentifierMono identifier={me.identifier} size={12}/>
            </div>
          </div>

          {hasArtistProfile(me) && (
            <Button variant="secondary" size="sm" icon="pencil"
              onClick={() => setEditingProfile(true)}>
              Profil bearbeiten
            </Button>
          )}
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10, marginTop: 24 }}>
          <MiniStat
            label="Hochladen"
            value={
              isBanned(me) ? 'Gebannt'
              : isBlocked(me) ? 'Gesperrt'
              : canSubmit(me) ? 'Freigeschaltet'
              : `Noch ${100 - me.playtime}h`
            }
            accent={
              isBanned(me) ? 'var(--danger)'
              : isBlocked(me) ? 'var(--danger)'
              : canSubmit(me) ? 'var(--success)'
              : 'var(--warning)'
            }
            icon={canSubmit(me) ? 'circle-check' : 'clock'}
          />
          <MiniStat
            label="Abstimmen"
            value={canVote(me) ? 'Ja' : 'Nein'}
            accent={canVote(me) ? 'var(--success)' : 'var(--fg-4)'}
            icon="thumbs-up"
          />
          <MiniStat
            label="Direkt entscheiden"
            value={canForceAccept(me) ? 'Admin' : 'Nein'}
            accent={canForceAccept(me) ? 'var(--gold)' : 'var(--fg-4)'}
            icon="bolt"
          />
          <MiniStat
            label="Verifiziert"
            value={isVerifiedArtist(me.identifier) ? 'Ja' : 'Nein'}
            accent={isVerifiedArtist(me.identifier) ? 'var(--aqua)' : 'var(--fg-4)'}
            icon="circle-check"
          />
        </div>
      </Glass>

      {/* Tracks + votes */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 16 }}>

        <Glass radius={20} padding={22}>
          <Eyebrow style={{ marginBottom: 14 }}>Meine Tracks · {mine.length}</Eyebrow>
          {mine.length === 0
            ? <div style={{ fontSize: 13, color: 'var(--fg-3)' }}>Noch keine Tracks hochgeladen.</div>
            : mine.map((s, idx) => (
              <TrackRow key={s.id} track={s}
                border={idx < mine.length - 1}
                meta={`${timeAgo(s.submittedAt)}${s.streams ? ` · ${numDE(s.streams)} Streams` : ''}`}
                trailing={<>
                  <StatusPill status={s.status}/>
                  <ShareButton track={s}/>
                  <AdminMenu sub={s} refresh={refresh}/>
                </>}/>
            ))}
        </Glass>

        <Glass radius={20} padding={22}>
          <Eyebrow style={{ marginBottom: 14 }}>Deine Stimmen · {myVotes.length}</Eyebrow>
          {myVotes.length === 0
            ? <div style={{ fontSize: 13, color: 'var(--fg-3)' }}>Du hast noch über nichts abgestimmt.</div>
            : myVotes.map((s, idx) => {
              const v = s.votes.find(v => v.identifier === me.identifier);
              return (
                <div key={s.id} style={{
                  display: 'flex', alignItems: 'center', gap: 12, padding: '10px 0',
                  borderBottom: idx < myVotes.length - 1 ? '1px solid var(--border-hairline)' : 'none',
                }}>
                  <Cover colors={s.cover} src={s.coverUrl} size={36} radius={8}/>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--foam)',
                      whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{s.title}</div>
                    <div style={{ fontSize: 11.5, color: 'var(--fg-3)' }}>{s.artist}</div>
                  </div>
                  <span style={{
                    fontSize: 12, fontWeight: 700,
                    color: v.vote === 'accept' ? 'var(--success)' : 'var(--danger)',
                    display: 'inline-flex', alignItems: 'center', gap: 4,
                  }}>
                    <ApIcon name={v.vote === 'accept' ? 'thumbs-up' : 'thumbs-down'} size={11}/>
                    {v.vote === 'accept' ? 'Dafür' : 'Dagegen'}
                  </span>
                </div>
              );
            })}
        </Glass>
      </div>

      {/* Second row — Zuletzt gehört + Meine Likes. Both lists
          mirror the same tables the ingame app writes to, so a
          play / like in either surface shows up in the other. */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 16, marginTop: 16 }}>
        <LibraryList
          title="Zuletzt gehört"
          tracks={library.recent}
          emptyText="Du hast noch nichts angehört. Spiel was im Player ab — auch ingame zählt."
          renderMeta={(t) => t.lastPlayed ? `${timeAgo(t.lastPlayed)} · ${t.userPlays}×` : t.artist}
        />
        <LibraryList
          title="Meine Likes"
          tracks={library.likes}
          emptyText="Noch keine Likes. Klick auf das Herz im Player."
          renderMeta={(t) => t.likedAt ? `geliked ${timeAgo(t.likedAt)}` : t.artist}
        />
      </div>
    </div>
  );
}

// Wrapper around the shared TrackRow primitive — `renderMeta` lets
// each caller (recents shows time + plays; likes shows liked-when)
// drop in its own meta-line variant without us needing two near-
// identical components.
function LibraryList({ title, tracks, emptyText, renderMeta }) {
  return (
    <Glass radius={20} padding={22}>
      <Eyebrow style={{ marginBottom: 14 }}>{title} · {tracks.length}</Eyebrow>
      {tracks.length === 0
        ? <div style={{ fontSize: 13, color: 'var(--fg-3)' }}>{emptyText}</div>
        : tracks.map((t, idx) => (
          <TrackRow key={t.id} track={t}
            border={idx < tracks.length - 1}
            meta={
              <>
                <ArtistLink identifier={t.identifier} name={t.artist} size={11.5}/>
                <span style={{ color: 'var(--fg-4)' }}> · </span>
                {renderMeta(t)}
              </>
            }
            trailing={<><ShareButton track={t}/><AdminMenu sub={t}/></>}/>
        ))}
    </Glass>
  );
}

// Small stat tile used by the identity card. Same shape as the
// stats screen's BigStat but at a quarter of the size — fits four
// across in the 4-column grid above.
function MiniStat({ label, value, accent, icon }) {
  return (
    <div style={{
      padding: '14px 16px', borderRadius: 14,
      background: 'var(--bg-input)',
      border: '1px solid var(--border-soft)',
    }}>
      <div style={{
        fontSize: 10.5, fontWeight: 700, letterSpacing: '0.18em',
        textTransform: 'uppercase', color: 'var(--fg-3)',
        display: 'flex', alignItems: 'center', gap: 6,
      }}>
        <ApIcon name={icon} size={10}/> {label}
      </div>
      <div style={{
        fontWeight: 800, fontSize: 18, color: accent,
        marginTop: 6, letterSpacing: '-0.01em',
      }}>{value}</div>
    </div>
  );
}

// Reusable for the "Gebannt" / "Gesperrt" hover pills next to the
// name. RolePill handles the always-present role chip; this one is
// specifically for sanction states that aren't part of the role tier.
function StatusBadge({ color, bg, icon, children }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '3px 10px', borderRadius: 999,
      fontSize: 10.5, fontWeight: 700, letterSpacing: 0.4, textTransform: 'uppercase',
      background: bg, color, border: `1px solid ${color}55`,
    }}>
      <ApIcon name={icon} size={11}/>
      {children}
    </span>
  );
}

window.ProfileScreen = ProfileScreen;
