import { useMemo, useState } from 'react'
import PublicLayout from '../../components/PublicLayout.jsx'
import PageHeader from '../../components/PageHeader.jsx'
import { Loading, ErrorState } from '../../components/PageState.jsx'
import { useAsync } from '../../lib/useAsync.js'
import { useShardFeed } from '../../lib/useShardFeed.js'
import { api } from '../../api/client.js'

// The guild board. Loaded once from /public/shard/guilds, then kept live by
// merging guild.update / guild.remove deltas; guild.join drives a small "recently
// joined" strip on top of the board.
const GUILD_KINDS = new Set(['guild.update', 'guild.remove', 'guild.join'])

function Leader({ leader }) {
  if (!leader || !leader.name) return <span className="dim">—</span>
  return <span>{leader.name}</span>
}

function GuildRow({ g }) {
  return (
    <div
      className="panel"
      style={{ padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 14 }}
    >
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, minWidth: 0 }}>
          {g.abbr && (
            <span
              className="sans"
              style={{
                flex: 'none',
                fontSize: '0.72rem',
                letterSpacing: '0.06em',
                color: 'var(--accent)',
                border: '1px solid rgba(201,162,75,0.4)',
                borderRadius: 5,
                padding: '1px 6px',
              }}
            >
              {g.abbr}
            </span>
          )}
          <strong
            className="display"
            style={{ fontSize: '1rem', color: 'var(--head)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}
          >
            {g.name || 'A guild'}
          </strong>
        </div>
        {g.alliance && (
          <div className="sans dim" style={{ fontSize: '0.76rem', marginTop: 2 }}>
            {g.alliance}
          </div>
        )}
      </div>
      <div className="sans" style={{ flex: 'none', textAlign: 'right', fontSize: '0.84rem', color: 'var(--ink)' }}>
        <div>
          <span style={{ color: '#7fd0a4' }}>{g.online ?? 0}</span>
          <span className="dim"> / {g.members ?? 0}</span>
        </div>
        <div className="dim" style={{ fontSize: '0.72rem', marginTop: 2 }}>
          <Leader leader={g.leader} />
        </div>
      </div>
    </div>
  )
}

export default function Guilds() {
  const { loading, error, data } = useAsync(() => api.shard.guilds())
  const { events, connected } = useShardFeed({ filter: GUILD_KINDS, max: 60 })
  const [q, setQ] = useState('')

  // Merge snapshot + live deltas by guild id (apply oldest → newest so live wins).
  const board = useMemo(() => {
    const map = new Map()
    for (const g of data || []) if (g && g.id != null) map.set(g.id, g)
    for (let i = events.length - 1; i >= 0; i -= 1) {
      const ev = events[i]
      if (ev.kind === 'guild.update' && ev.id != null) map.set(ev.id, ev)
      else if (ev.kind === 'guild.remove' && ev.id != null) map.delete(ev.id)
    }
    return [...map.values()]
  }, [data, events])

  // Recent joins strip (newest first, deduped, capped).
  const joins = useMemo(
    () => events.filter((e) => e.kind === 'guild.join' && e.who).slice(0, 6),
    [events],
  )

  const filtered = useMemo(() => {
    const needle = q.trim().toLowerCase()
    const rows = needle
      ? board.filter((g) =>
          [g.name, g.abbr, g.alliance].some((v) => v && v.toLowerCase().includes(needle)),
        )
      : board
    return [...rows].sort((a, b) => (a.name || '').localeCompare(b.name || ''))
  }, [board, q])

  const totalMembers = board.reduce((n, g) => n + (Number(g.members) || 0), 0)

  return (
    <PublicLayout section="website">
      <div className="shell-narrow page-body">
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
          <PageHeader eyebrow="Live" title="Guilds" lead="Every guild on the shard — rosters, alliances and who's online, updating in real time." />
          <span className="sans" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: '0.74rem', color: connected ? '#7fd0a4' : 'var(--muted)', flex: 'none', marginTop: 6 }}>
            <span style={{ width: 8, height: 8, borderRadius: '50%', background: connected ? '#7fd0a4' : 'var(--dim)' }} />
            {connected ? 'Live' : 'Offline'}
          </span>
        </div>

        {loading && <Loading />}
        {error && <ErrorState message="Could not load the guild board right now." />}

        {!loading && !error && (
          <>
            {board.length === 0 ? (
              <section className="panel" style={{ padding: 24, textAlign: 'center' }}>
                <p className="sans dim" style={{ margin: 0 }}>No guilds are being tracked right now.</p>
              </section>
            ) : (
              <>
                {joins.length > 0 && (
                  <section className="panel" style={{ padding: '12px 16px', marginBottom: 18 }}>
                    <div className="sans" style={{ color: 'var(--accent)', fontSize: '0.66rem', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 8 }}>
                      Recently joined
                    </div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
                      {joins.map((j) => (
                        <div key={j._id} className="sans" style={{ fontSize: '0.84rem', color: 'var(--ink)' }}>
                          <strong style={{ color: 'var(--head)' }}>{j.who.name}</strong>
                          <span className="dim"> joined </span>
                          {j.abbr ? `[${j.abbr}] ` : ''}{j.name}
                        </div>
                      ))}
                    </div>
                  </section>
                )}

                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 14 }}>
                  <p className="sans" style={{ color: 'var(--accent)', fontSize: '0.8rem', margin: 0 }}>
                    {board.length} guilds · {totalMembers.toLocaleString()} members
                  </p>
                  <input
                    className="input sans"
                    value={q}
                    onChange={(e) => setQ(e.target.value)}
                    placeholder="Search guilds…"
                    style={{ flex: 'none', width: 190, maxWidth: '50%', fontSize: '0.84rem' }}
                  />
                </div>

                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                  {filtered.map((g) => <GuildRow key={g.id} g={g} />)}
                </div>
                {filtered.length === 0 && (
                  <p className="sans dim" style={{ textAlign: 'center', marginTop: 20 }}>No guilds match “{q}”.</p>
                )}
              </>
            )}
          </>
        )}
      </div>
    </PublicLayout>
  )
}
