import { useMemo, useState } from 'react'
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'

// Staff-only FULL house registry (admin + moderator). Owner, price, co-owners and
// decay — everything the public board hides. Loaded from /admin/shard/houses, kept
// live from the admin SSE channel (house.update / house.remove).
const HOUSE_KINDS = new Set(['house.update', 'house.remove', 'house.decay'])

const DECAY_TONE = {
  LikeNew: '#7fd0a4', Ageless: '#7fd0a4', Slightly: '#a9cf8a', Somewhat: '#d7c56a',
  Fairly: '#e0a95f', Greatly: '#d9736f', IDOC: '#e05a5a', Collapsed: '#8c96a5',
}

function DecayBadge({ decay, isIdoc }) {
  const label = isIdoc ? 'IDOC' : decay
  if (!label) return null
  const tone = DECAY_TONE[label] || 'var(--muted)'
  return (
    <span className="sans" style={{ flex: 'none', fontSize: '0.68rem', color: tone, border: `1px solid ${tone}66`, borderRadius: 999, padding: '2px 8px' }}>
      {label}
    </span>
  )
}

function ownerLabel(h) {
  return h.ownerName || h.ownerAcct || null
}

function HouseRow({ h }) {
  const owner = ownerLabel(h)
  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: 'center', gap: 8, minWidth: 0 }}>
          <strong className="display" style={{ fontSize: '1rem', color: 'var(--head)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
            {h.name || 'An unnamed house'}
          </strong>
          <DecayBadge decay={h.decay} isIdoc={h.isIdoc} />
        </div>
        <div className="sans dim" style={{ fontSize: '0.78rem', marginTop: 3 }}>
          {owner ? <>Owned by <span style={{ color: 'var(--ink)' }}>{owner}</span></> : 'No owner'}
          {(h.coOwners || h.friends) ? ` · ${h.coOwners || 0} co-owners, ${h.friends || 0} friends` : ''}
        </div>
        <div className="sans dim" style={{ fontSize: '0.72rem', marginTop: 2 }}>
          {h.region || h.map || '—'}{h.x != null ? ` (${h.x}, ${h.y})` : ''}
        </div>
      </div>
      {h.price != null && (
        <div className="sans" style={{ flex: 'none', textAlign: 'right' }}>
          <div style={{ fontSize: '0.92rem', color: 'var(--head)', fontVariantNumeric: 'tabular-nums' }}>{Number(h.price).toLocaleString()}</div>
          <div className="dim" style={{ fontSize: '0.64rem', letterSpacing: '0.04em', textTransform: 'uppercase' }}>placement value</div>
        </div>
      )}
    </div>
  )
}

export default function HousesAdmin() {
  const { loading, error, data } = useAsync(() => api.admin.shard.houses())
  // Full registry deltas ride the admin SSE channel (never the public one).
  const { events, connected } = useShardFeed({ url: api.adminShardStreamUrl, filter: HOUSE_KINDS, max: 80 })
  const [q, setQ] = useState('')

  const board = useMemo(() => {
    const map = new Map()
    for (const h of data || []) if (h && h.serial) map.set(h.serial, h)
    for (let i = events.length - 1; i >= 0; i -= 1) {
      const ev = events[i]
      if (!ev.serial) continue
      if (ev.kind === 'house.update') {
        map.set(ev.serial, { ...ev, ownerName: ev.owner?.name ?? ev.ownerName, ownerAcct: ev.owner?.acct ?? ev.ownerAcct })
      } else if (ev.kind === 'house.remove') {
        map.delete(ev.serial)
      } else if (ev.kind === 'house.decay') {
        const cur = map.get(ev.serial) || { serial: ev.serial, name: ev.name, region: ev.region, map: ev.map, x: ev.x, y: ev.y }
        map.set(ev.serial, { ...cur, isIdoc: String(ev.to).toUpperCase() === 'IDOC' })
      }
    }
    return [...map.values()]
  }, [data, events])

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

  if (loading) return <Loading />
  if (error) return <ErrorState message="Could not load the house registry." />

  return (
    <section>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 16 }}>
        <p className="sans" style={{ color: 'var(--accent)', fontSize: '0.82rem', margin: 0 }}>
          {board.length.toLocaleString()} houses
          <span className="dim" style={{ marginLeft: 10, color: connected ? '#7fd0a4' : 'var(--muted)' }}>{connected ? '● live' : '○ offline'}</span>
        </p>
        <input className="input sans" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search by owner, region…" style={{ flex: 'none', width: 230, maxWidth: '55%', fontSize: '0.84rem' }} />
      </div>
      {board.length === 0 ? (
        <div className="panel" style={{ padding: 24, textAlign: 'center' }}>
          <p className="sans dim" style={{ margin: 0 }}>No houses are being tracked right now.</p>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {filtered.map((h) => <HouseRow key={h.serial} h={h} />)}
        </div>
      )}
      {board.length > 0 && filtered.length === 0 && (
        <p className="sans dim" style={{ textAlign: 'center', marginTop: 20 }}>No houses match “{q}”.</p>
      )}
    </section>
  )
}
