import { Link } from 'react-router-dom'
import { useShardFeed } from '../../lib/useShardFeed.js'
import { describe } from '../../lib/shardEvents.js'
import { ago } from '../../lib/format.js'
import api from '../../api.js'
import PlayersOnline from '../../components/PlayersOnline.jsx'
import { ErrorState, Loading, PageHeader, PublicLayout, useAsync, useAuth } from '../../core.js'

// Flavor line under the online/offline banner: online, configured-but-down, or
// not configured yet.
function statusMessage(online, enabled) {
  if (online) return 'The gate to Britannia stands open.'
  if (enabled) return 'The link to the game world is down — checking back automatically.'
  return 'Live shard data is not configured yet.'
}

// ── Gold-supply sparkline ───────────────────────────────────────────────────
function Sparkline({ series }) {
  if (!series || series.length < 2) return null
  const w = 320
  const h = 56
  const golds = series.map((s) => Number(s.gold) || 0)
  const min = Math.min(...golds)
  const max = Math.max(...golds)
  const span = max - min || 1
  const pts = series
    .map((s, i) => {
      const x = (i / (series.length - 1)) * w
      const y = h - ((Number(s.gold) || 0) - min) / span * h
      return `${x.toFixed(1)},${y.toFixed(1)}`
    })
    .join(' ')
  return (
    <svg viewBox={`0 0 ${w} ${h}`} width="100%" height={h} preserveAspectRatio="none" aria-hidden="true">
      <polyline points={pts} fill="none" stroke="var(--accent)" strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  )
}

// ── Stat tile (matches Status.jsx) ──────────────────────────────────────────
function Stat({ value, label }) {
  return (
    <div className="panel" style={{ padding: 20, textAlign: 'center' }}>
      <div className="display" style={{ fontSize: '1.6rem', color: 'var(--head)' }}>{value}</div>
      <div className="sans" style={{ color: 'var(--accent)', fontSize: '0.7rem', letterSpacing: '0.12em', textTransform: 'uppercase', marginTop: 6 }}>
        {label}
      </div>
    </div>
  )
}

export default function Shard() {
  const { loading, error, data } = useAsync(() =>
    Promise.all([
      api.shard.status(),
      api.shard.idoc(),
      api.shard.economy(60),
      api.shard.online(),
    ]).then(([status, idoc, economy, online]) => ({ status, idoc, economy, online })),
  )
  const { events, connected } = useShardFeed({ max: 30 })
  const { user } = useAuth()
  // Staff in-game location is privileged: only admins/moderators see it. Players
  // and the public see that staff are online but not where. The server enforces
  // this too (it omits the location fields entirely for non-privileged callers).
  const canSeeLocation = user?.role === 'admin' || user?.role === 'moderator'

  const status = data?.status
  const online = status?.pluginConnected
  const gold = status?.economy?.gold

  return (
    <PublicLayout section="website">
      <div className="shell-narrow page-body">
        <PageHeader eyebrow="Live" title="Shard" />

        {loading && <Loading />}
        {error && <ErrorState message="Could not load shard data right now." />}

        {!loading && !error && data && (
          <>
            <ConnectionBanner online={online} status={status} />

            {/* Stat tiles */}
            <section className="grid-2" style={{ gap: 14, marginBottom: 24 }}>
              <Stat value={gold != null ? `${Number(gold).toLocaleString()}` : '—'} label="Gold supply" />
              <Stat value={online ? 'Up' : 'Down'} label="Shard link" />
            </section>

            {/* Live players-online breakdown (total + region buckets) */}
            <div style={{ marginBottom: 24 }}>
              <PlayersOnline />
            </div>

            <StaffOnline list={data.online} canSeeLocation={canSeeLocation} />

            {/* Economy sparkline */}
            {data.economy && data.economy.length > 1 && (
              <section className="panel" style={{ padding: 20, marginBottom: 24 }}>
                <div className="sans" style={{ color: 'var(--accent)', fontSize: '0.7rem', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 10 }}>
                  Gold supply over time
                </div>
                <Sparkline series={data.economy} />
              </section>
            )}

            <div style={{ marginBottom: 24 }}>
              {/* Latest IDOC */}
              <FeedList
                title="Houses in danger (IDOC)"
                empty="No houses are collapsing right now."
                items={data.idoc.map((h) => {
                  const region = h.region ? ` — ${h.region}` : ''
                  return {
                    id: h.serial,
                    text: `${h.name || 'A house'}${region}`,
                    when: h.updatedAt,
                  }
                })}
              />
            </div>

            {/* Live ticker */}
            <section className="panel" style={{ padding: 20 }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
                <div className="sans" style={{ color: 'var(--accent)', fontSize: '0.7rem', letterSpacing: '0.12em', textTransform: 'uppercase' }}>
                  Live feed
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                  <Link to="/uo/shard/activity" className="sans" style={{ color: 'var(--accent)', textDecoration: 'none', fontSize: '0.78rem' }}>
                    View all activity →
                  </Link>
                  <span className="sans" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: '0.74rem', color: connected ? '#7fd0a4' : 'var(--muted)' }}>
                    <span style={{ width: 8, height: 8, borderRadius: '50%', background: connected ? '#7fd0a4' : 'var(--dim)' }} />
                    {connected ? 'Live' : 'Offline'}
                  </span>
                </div>
              </div>
              {events.length === 0 ? (
                <p className="sans dim" style={{ margin: 0, fontSize: '0.88rem' }}>
                  Waiting for something to happen in the world…
                </p>
              ) : (
                <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {events.map((ev) => (
                    <li key={ev._id} className="sans" style={{ display: 'flex', justifyContent: 'space-between', gap: 12, fontSize: '0.9rem', color: 'var(--ink)' }}>
                      <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{describe(ev)}</span>
                      <span className="dim" style={{ flex: 'none', fontSize: '0.78rem' }}>{ago(ev.t)}</span>
                    </li>
                  ))}
                </ul>
              )}
            </section>
          </>
        )}
      </div>
    </PublicLayout>
  )
}

// Online/offline banner with the flavor line under it.
function ConnectionBanner({ online, status }) {
  return (
    <section
      style={{
        display: 'flex',
        alignItems: 'center',
        gap: 16,
        padding: '24px 26px',
        border: `1px solid ${online ? 'rgba(95,185,138,0.45)' : '#5a4a2a'}`,
        borderRadius: 10,
        background: online
          ? 'linear-gradient(180deg,rgba(22,46,34,0.5),rgba(16,26,20,0.4))'
          : 'linear-gradient(180deg,rgba(58,46,22,0.5),rgba(30,26,16,0.4))',
        marginBottom: 24,
      }}
    >
      <span
        style={{
          flex: 'none',
          width: 12,
          height: 12,
          borderRadius: '50%',
          background: online ? 'var(--mode-live)' : 'var(--mode-maint)',
          boxShadow: `0 0 12px ${online ? 'rgba(95,185,138,0.7)' : 'rgba(230,194,106,0.7)'}`,
        }}
      />
      <div>
        <strong className="display" style={{ display: 'block', fontSize: '1.2rem', color: online ? '#bfe6cf' : '#f0e3c4' }}>
          {online ? 'The shard is online' : 'The shard is offline'}
        </strong>
        <span className="sans" style={{ color: online ? '#a9cdb8' : '#cdbf9a', fontSize: '0.98rem' }}>
          {statusMessage(online, status?.enabled)}
        </span>
      </div>
    </section>
  )
}

// Linked staff accounts currently online; in-game location is admin/mod-only.
function StaffOnline({ list, canSeeLocation }) {
  return (
    <section className="panel" style={{ padding: 20, marginBottom: 24 }}>
      <div className="sans" style={{ color: 'var(--accent)', fontSize: '0.7rem', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 12 }}>
        Staff online
      </div>
      {(!list || list.length === 0) ? (
        <p className="sans dim" style={{ margin: 0, fontSize: '0.88rem' }}>No staff are online right now.</p>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {list.map((p) => (
            <div key={p.serial} className="sans" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, fontSize: '0.9rem', color: 'var(--ink)' }}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
                <span style={{ flex: 'none', width: 8, height: 8, borderRadius: '50%', background: '#7fd0a4' }} />
                {p.name || p.serial}
              </span>
              {canSeeLocation && (
                <span className="dim" style={{ flex: 'none', fontSize: '0.78rem' }}>
                  {p.map || '—'}{p.x != null ? ` (${p.x}, ${p.y})` : ''}
                </span>
              )}
            </div>
          ))}
        </div>
      )}
    </section>
  )
}

function FeedList({ title, items, empty }) {
  return (
    <section className="panel" style={{ padding: 20 }}>
      <div className="sans" style={{ color: 'var(--accent)', fontSize: '0.7rem', letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 12 }}>
        {title}
      </div>
      {items.length === 0 ? (
        <p className="sans dim" style={{ margin: 0, fontSize: '0.88rem' }}>{empty}</p>
      ) : (
        <ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 10 }}>
          {items.map((it) => (
            <li key={it.id} className="sans" style={{ display: 'flex', justifyContent: 'space-between', gap: 12, fontSize: '0.9rem', color: 'var(--ink)' }}>
              <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{it.text}</span>
              <span className="dim" style={{ flex: 'none', fontSize: '0.78rem' }}>{ago(it.when)}</span>
            </li>
          ))}
        </ul>
      )}
    </section>
  )
}
