import { useEffect, useMemo, useRef, useState } from 'react'
import Tree from '../Tree/Tree'
import FallingLeaves from '../Tree/FallingLeaves'

const numberFormat = new Intl.NumberFormat('en-GB')
const dateFormat = new Intl.DateTimeFormat('en-GB', {
  dateStyle: 'medium',
  timeStyle: 'short',
})

const apiEndpoints = {
  health: '/health',
  uptime: '/api/uptime',
  viewers: '/api/viewers',
  viewerEvent: '/api/viewers/event',
  teams: '/api/tss/leaderboard/teams?limit=100',
  teamsHealth: '/api/tss/leaderboard/teams?limit=1',
  resolve: (name) => `/api/tss/teams/resolve?name=${encodeURIComponent(name)}`,
  detail: (name) => `/api/tss/teams/${encodeURIComponent(name)}`,
  history: (name) => `/api/tss/teams/${encodeURIComponent(name)}/history`,
  games: (name) => `/api/tss/teams/${encodeURIComponent(name)}/games`,
}

const navItems = [
  { path: '/', label: 'Home' },
  { path: '/teams', label: 'Team leaderboard' },
  { path: '/battle-logs', label: 'Battle Logs' },
  { path: '/viewers', label: 'Viewers' },
]

const analyticsConsentKey = 'tssbot.analyticsConsent'
const analyticsVisitorKey = 'tssbot.analyticsVisitor'

async function fetchJson(path, signal) {
  const response = await fetch(path, {
    signal,
    headers: { Accept: 'application/json' },
  })
  const body = await response.json().catch(() => null)

  if (!response.ok) {
    throw new Error(body?.error || `Request failed with ${response.status}`)
  }

  return body
}

function parseRoute(pathname = window.location.pathname) {
  if (pathname === '/') return { page: 'home', teamName: '' }
  if (pathname === '/teams') return { page: 'teams', teamName: '' }
  if (pathname === '/uptime') return { page: 'uptime', teamName: '' }
  if (pathname === '/viewers') return { page: 'viewers', teamName: '' }
  if (pathname.startsWith('/teams/')) {
    const teamName = decodeURIComponent(pathname.slice('/teams/'.length))
    return { page: 'team', teamName }
  }
  if (pathname === '/battle-logs' || pathname === '/live') return { page: 'battle-logs', teamName: '' }
  return { page: 'home', teamName: '' }
}

function teamPath(name) {
  return `/teams/${encodeURIComponent(name)}`
}

function formatNumber(value) {
  return numberFormat.format(Number(value || 0))
}

function formatDate(timestamp) {
  if (!timestamp) return 'Unknown time'
  return dateFormat.format(new Date(Number(timestamp) * 1000))
}

function bestTeamName(team) {
  return team?.tag_name || team?.short_name || team?.long_name || ''
}

function storedConsent() {
  try {
    return window.localStorage.getItem(analyticsConsentKey) || ''
  } catch {
    return ''
  }
}

function stableId(storageKey) {
  try {
    const existing = window.localStorage.getItem(storageKey)
    if (existing) return existing

    const id =
      window.crypto?.randomUUID?.() ||
      `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`
    window.localStorage.setItem(storageKey, id)
    return id
  } catch {
    return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`
  }
}

const analyticsSessionId =
  window.crypto?.randomUUID?.() ||
  `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`

function browserName() {
  const ua = navigator.userAgent
  if (ua.includes('Edg/')) return 'Microsoft Edge'
  if (ua.includes('OPR/')) return 'Opera'
  if (ua.includes('Firefox/')) return 'Firefox'
  if (ua.includes('Chrome/') && !ua.includes('Chromium/')) return 'Chrome'
  if (ua.includes('Safari/') && ua.includes('Version/')) return 'Safari'
  return 'Unknown'
}

function operatingSystem() {
  const ua = navigator.userAgent
  if (ua.includes('Windows NT')) return 'Windows'
  if (ua.includes('Android')) return 'Android'
  if (/iPhone|iPad|iPod/.test(ua)) return 'iOS'
  if (ua.includes('Mac OS X')) return 'macOS'
  if (ua.includes('Linux')) return 'Linux'
  return 'Unknown'
}

function deviceType() {
  const ua = navigator.userAgent
  if (/Mobi|Android|iPhone|iPod/.test(ua)) return 'Mobile'
  if (/iPad|Tablet/.test(ua)) return 'Tablet'
  return 'Desktop'
}

function routeLabel(route) {
  if (route.page === 'team' && route.teamName) return `Team: ${route.teamName}`
  if (route.page === 'teams') return 'Team leaderboard'
  if (route.page === 'battle-logs') return 'Battle Logs'
  if (route.page === 'uptime') return 'Uptime'
  if (route.page === 'viewers') return 'viewers'
  return 'Home'
}

async function fetchRecentTssGames(teams, signal) {
  const teamNames = teams.map(bestTeamName).filter(Boolean).slice(0, 12)

  if (!teamNames.length) {
    return { matches: [] }
  }

  const responses = await Promise.allSettled(
    teamNames.map((name) => fetchJson(apiEndpoints.games(name), signal).then((data) => ({ name, data }))),
  )
  const bySession = new Map()

  responses.forEach((result) => {
    if (result.status !== 'fulfilled') return

    const { name, data } = result.value
    ;(data.games || []).forEach((game) => {
      if (!game.session_id) return

      const existing = bySession.get(game.session_id)
      const currentTimestamp = Number(game.timestamp || 0)
      if (existing && Number(existing.timestamp || 0) >= currentTimestamp) return

      bySession.set(game.session_id, {
        ...game,
        team_name: data.tag_name || name,
        long_name: data.long_name || '',
      })
    })
  })

  return {
    matches: Array.from(bySession.values())
      .sort((a, b) => Number(b.timestamp || 0) - Number(a.timestamp || 0))
      .slice(0, 50),
  }
}

function Stat({ label, value }) {
  return (
    <div className="border-l border-border pl-4">
      <p className="text-xs font-semibold uppercase tracking-wide text-text-soft">
        {label}
      </p>
      <p className="mt-1 text-2xl font-semibold text-text">{value}</p>
    </div>
  )
}

function App() {
  const [route, setRoute] = useState(() => parseRoute())
  const [leaderboard, setLeaderboard] = useState({ status: 'idle', data: null, error: null })
  const [live, setLive] = useState({ status: 'idle', data: null, error: null })
  const [uptime, setUptime] = useState({ status: 'idle', checks: [], history: [], updatedAt: null })
  const [viewers, setViewers] = useState({ status: 'idle', data: null, error: null, updatedAt: null })
  const [analyticsConsent, setAnalyticsConsent] = useState(() => storedConsent())
  const [teamQuery, setTeamQuery] = useState('')
  const [searchHint, setSearchHint] = useState({ status: 'idle', name: '' })
  const [profile, setProfile] = useState({
    teamName: '',
    detail: { status: 'idle', data: null, error: null },
    history: { status: 'idle', data: null, error: null },
    games: { status: 'idle', data: null, error: null },
  })
  const teams = useMemo(
    () => leaderboard.data?.teams || leaderboard.data?.squadrons || [],
    [leaderboard.data],
  )
  const matches = live.data?.matches || []

  function navigate(path) {
    window.history.pushState({}, '', path)
    setRoute(parseRoute(path))
  }

  useEffect(() => {
    const onPopState = () => setRoute(parseRoute())
    window.addEventListener('popstate', onPopState)
    return () => window.removeEventListener('popstate', onPopState)
  }, [])

  useEffect(() => {
    const title =
      route.page === 'team' && route.teamName
        ? `${route.teamName} | Toothless' TSS Bot`
        : route.page === 'teams'
          ? "Team leaderboard | Toothless' TSS Bot"
          : route.page === 'battle-logs'
            ? "Battle Logs | Toothless' TSS Bot"
            : route.page === 'uptime'
              ? "Uptime | Toothless' TSS Bot"
              : route.page === 'viewers'
                ? "viewers | Toothless' TSS Bot"
            : "Toothless' TSS Bot"

    document.title = title
  }, [route.page, route.teamName])

  useEffect(() => {
    if (analyticsConsent !== 'analytics') return

    const visitorId = stableId(analyticsVisitorKey)
    let stopped = false

    function sendViewerEvent(eventType) {
      if (stopped) return

      const body = {
        consent: 'analytics',
        event_type: eventType,
        visitor_id: visitorId,
        session_id: analyticsSessionId,
        page_path: window.location.pathname,
        page_title: routeLabel(route),
        referrer: document.referrer,
        browser: browserName(),
        os: operatingSystem(),
        device: deviceType(),
        screen: `${window.screen.width}x${window.screen.height}`,
        language: navigator.language,
        timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
        metadata: {
          color_depth: window.screen.colorDepth,
          viewport: `${window.innerWidth}x${window.innerHeight}`,
        },
      }

      fetch(apiEndpoints.viewerEvent, {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(body),
        keepalive: true,
      }).catch(() => {})
    }

    sendViewerEvent('page_view')
    const timer = window.setInterval(() => sendViewerEvent('heartbeat'), 30000)
    const onVisibilityChange = () => {
      if (document.visibilityState === 'visible') sendViewerEvent('heartbeat')
    }
    document.addEventListener('visibilitychange', onVisibilityChange)

    return () => {
      stopped = true
      window.clearInterval(timer)
      document.removeEventListener('visibilitychange', onVisibilityChange)
    }
  }, [analyticsConsent, route])

  useEffect(() => {
    const onKeyDown = (event) => {
      if (event.key === 'Escape') {
        navigate('/')
      }
    }

    window.addEventListener('keydown', onKeyDown)
    return () => window.removeEventListener('keydown', onKeyDown)
  }, [])

  useEffect(() => {
    const query = teamQuery.trim()
    if (query.length < 2) {
      setSearchHint({ status: 'idle', name: '' })
      return
    }

    const controller = new AbortController()
    const timer = window.setTimeout(() => {
      setSearchHint({ status: 'loading', name: '' })
      fetchJson(apiEndpoints.resolve(query), controller.signal)
        .then((data) => {
          const name = data.tag_name || data.short_name || data.long_name || query
          setSearchHint({ status: 'ready', name })
        })
        .catch(() => {
          if (!controller.signal.aborted) {
            setSearchHint({ status: 'error', name: '' })
          }
        })
    }, 350)

    return () => {
      window.clearTimeout(timer)
      controller.abort()
    }
  }, [teamQuery])

  useEffect(() => {
    if (!['home', 'teams', 'team', 'battle-logs'].includes(route.page)) return
    if (leaderboard.status === 'ready' || leaderboard.status === 'loading') return

    const controller = new AbortController()
    setLeaderboard({ status: 'loading', data: null, error: null })

    fetchJson(apiEndpoints.teams, controller.signal)
      .then((data) => setLeaderboard({ status: 'ready', data, error: null }))
      .catch((error) => {
        if (!controller.signal.aborted) {
          setLeaderboard({ status: 'error', data: null, error: error.message })
        }
      })

    return () => controller.abort()
  }, [leaderboard.status, route.page])

  useEffect(() => {
    if (!['home', 'teams', 'team', 'battle-logs'].includes(route.page)) return

    const controller = new AbortController()
    const timer = window.setInterval(() => {
      fetchJson(apiEndpoints.teams, controller.signal)
        .then((data) => setLeaderboard({ status: 'ready', data, error: null }))
        .catch((error) => {
          if (!controller.signal.aborted) {
            setLeaderboard((current) => ({ ...current, error: error.message }))
          }
        })
    }, 60000)

    return () => {
      window.clearInterval(timer)
      controller.abort()
    }
  }, [route.page])

  useEffect(() => {
    if (!['home', 'battle-logs'].includes(route.page)) return
    if (!teams.length) return

    const controller = new AbortController()
    setLive((current) =>
      current.status === 'ready' ? current : { status: 'loading', data: null, error: null },
    )

    fetchRecentTssGames(teams, controller.signal)
      .then((data) => setLive({ status: 'ready', data, error: null }))
      .catch((error) => {
        if (!controller.signal.aborted) {
          setLive({ status: 'error', data: null, error: error.message })
        }
      })

    return () => controller.abort()
  }, [route.page, teams])

  useEffect(() => {
    if (!['home', 'battle-logs'].includes(route.page)) return
    if (!teams.length) return

    const controller = new AbortController()
    const timer = window.setInterval(() => {
      fetchRecentTssGames(teams, controller.signal)
        .then((data) => setLive({ status: 'ready', data, error: null }))
        .catch((error) => {
          if (!controller.signal.aborted) {
            setLive((current) => ({ ...current, error: error.message }))
          }
        })
    }, 15000)

    return () => {
      window.clearInterval(timer)
      controller.abort()
    }
  }, [route.page, teams])

  useEffect(() => {
    if (route.page !== 'team' || !route.teamName) return

    const controller = new AbortController()
    setProfile({
      teamName: route.teamName,
      detail: { status: 'loading', data: null, error: null },
      history: { status: 'loading', data: null, error: null },
      games: { status: 'loading', data: null, error: null },
    })

    Promise.allSettled([
      fetchJson(apiEndpoints.detail(route.teamName), controller.signal),
      fetchJson(apiEndpoints.history(route.teamName), controller.signal),
      fetchJson(apiEndpoints.games(route.teamName), controller.signal),
    ]).then(([detailResult, historyResult, gamesResult]) => {
      if (controller.signal.aborted) return

      setProfile({
        teamName: route.teamName,
        detail:
          detailResult.status === 'fulfilled'
            ? { status: 'ready', data: detailResult.value, error: null }
            : { status: 'error', data: null, error: detailResult.reason.message },
        history:
          historyResult.status === 'fulfilled'
            ? { status: 'ready', data: historyResult.value, error: null }
            : { status: 'error', data: null, error: historyResult.reason.message },
        games:
          gamesResult.status === 'fulfilled'
            ? { status: 'ready', data: gamesResult.value, error: null }
            : { status: 'error', data: null, error: gamesResult.reason.message },
      })
    })

    return () => controller.abort()
  }, [route.page, route.teamName])

  useEffect(() => {
    if (route.page !== 'uptime') return

    const controller = new AbortController()

    async function loadUptime() {
      setUptime((current) => ({
        status: current.status === 'ready' ? 'refreshing' : 'loading',
        checks: current.checks,
        history: current.history,
        updatedAt: current.updatedAt,
      }))

      fetchJson(apiEndpoints.uptime, controller.signal)
        .then((data) => {
          const latest = data.latest
          const checks = latest
            ? [
              {
                name: 'Website',
                detail: 'App shell and static assets',
                ok: latest.website_ok,
                label: latest.details?.website?.label || (latest.website_ok ? 'Online' : 'Issue'),
                latency: latest.latency_ms,
              },
              {
                name: 'Health endpoint',
                detail: apiEndpoints.health,
                ok: latest.health_ok,
                label: latest.details?.health?.label || (latest.health_ok ? 'Operational' : 'Issue'),
                latency: latest.latency_ms,
              },
              {
                name: 'TSS data proxy',
                detail: apiEndpoints.teamsHealth,
                ok: latest.tss_ok,
                label: latest.details?.tss?.label || (latest.tss_ok ? 'Operational' : 'Issue'),
                latency: latest.details?.tss?.latency_ms || latest.latency_ms,
              },
            ]
            : []

          setUptime({
            status: 'ready',
            checks,
            history: (data.history || []).map((sample) => ({
              timestamp: new Date(sample.checked_at).getTime(),
              onlineChecks: [sample.website_ok, sample.health_ok, sample.tss_ok].filter(Boolean).length,
              totalChecks: 3,
              ok: sample.ok,
            })),
            updatedAt: latest ? new Date(latest.checked_at).getTime() : null,
            configured: data.configured,
          })
        })
        .catch((error) => {
          if (controller.signal.aborted) return

          setUptime({
            status: 'error',
            updatedAt: null,
            configured: false,
            history: [],
            checks: [
              {
                name: 'Website',
                detail: 'App shell and static assets',
                ok: true,
                label: 'Online',
                latency: 0,
              },
              {
                name: 'Health endpoint',
                detail: apiEndpoints.health,
                ok: false,
                label: error.message,
                latency: 0,
              },
              {
                name: 'TSS data proxy',
                detail: apiEndpoints.teamsHealth,
                ok: false,
                label: 'Uptime history unavailable',
                latency: 0,
              },
            ],
          })
        })
    }

    loadUptime()
    const timer = window.setInterval(loadUptime, 60000)

    return () => {
      window.clearInterval(timer)
      controller.abort()
    }
  }, [route.page])

  useEffect(() => {
    if (route.page !== 'viewers') return

    const controller = new AbortController()

    function loadViewers() {
      setViewers((current) => ({
        status: current.status === 'ready' ? 'refreshing' : 'loading',
        data: current.data,
        error: null,
        updatedAt: current.updatedAt,
      }))

      fetchJson(apiEndpoints.viewers, controller.signal)
        .then((data) => {
          setViewers({
            status: 'ready',
            data,
            error: null,
            updatedAt: Date.now(),
          })
        })
        .catch((error) => {
          if (!controller.signal.aborted) {
            setViewers((current) => ({ ...current, status: 'error', error: error.message }))
          }
        })
    }

    loadViewers()
    const timer = window.setInterval(loadViewers, 5000)

    return () => {
      window.clearInterval(timer)
      controller.abort()
    }
  }, [route.page])

  useEffect(() => {
    if (route.page !== 'team' || !route.teamName) return

    const controller = new AbortController()
    const timer = window.setInterval(() => {
      Promise.allSettled([
        fetchJson(apiEndpoints.detail(route.teamName), controller.signal),
        fetchJson(apiEndpoints.history(route.teamName), controller.signal),
        fetchJson(apiEndpoints.games(route.teamName), controller.signal),
      ]).then(([detailResult, historyResult, gamesResult]) => {
        if (controller.signal.aborted) return

        setProfile((current) => ({
          teamName: route.teamName,
          detail:
            detailResult.status === 'fulfilled'
              ? { status: 'ready', data: detailResult.value, error: null }
              : current.detail,
          history:
            historyResult.status === 'fulfilled'
              ? { status: 'ready', data: historyResult.value, error: null }
              : current.history,
          games:
            gamesResult.status === 'fulfilled'
              ? { status: 'ready', data: gamesResult.value, error: null }
              : current.games,
        }))
      })
    }, 60000)

    return () => {
      window.clearInterval(timer)
      controller.abort()
    }
  }, [route.page, route.teamName])

  const topTeamName = bestTeamName(teams[0])
  const searchPlaceholder =
    searchHint.status === 'ready' ? `Found ${searchHint.name}` : topTeamName || 'Search teams'

  async function handleTeamSearch(event) {
    event.preventDefault()
    const name = teamQuery.trim()
    if (!name) return

    try {
      const resolved = await fetchJson(apiEndpoints.resolve(name))
      navigate(teamPath(resolved.tag_name || resolved.short_name || resolved.long_name || name))
    } catch {
      navigate(teamPath(name))
    }
  }

  function chooseAnalyticsConsent(value) {
    try {
      window.localStorage.setItem(analyticsConsentKey, value)
    } catch {
      // Local storage can be blocked; the in-memory choice still controls this session.
    }
    setAnalyticsConsent(value)
  }

  const activeNavPath =
    route.page === 'team'
      ? '/teams'
      : route.page === 'battle-logs'
        ? '/battle-logs'
        : route.page === 'viewers'
          ? '/viewers'
        : window.location.pathname

  return (
    <main className="min-h-screen bg-bg text-text">
      <header className="sticky top-0 z-50 border-b border-border bg-bg/90 backdrop-blur">
        <div className="mx-auto flex w-full max-w-7xl flex-col gap-3 px-5 py-3 sm:px-8 xl:flex-row xl:items-center">
          <button className="shrink-0 text-left" onClick={() => navigate('/')} type="button">
            <span className="text-lg font-bold tracking-tight">Toothless&apos; TSS Bot</span>
          </button>

          <nav className="flex flex-wrap items-center gap-1 rounded-lg bg-surface/70 p-1 xl:ml-8">
            {navItems.map((item) => (
              <button
                className={`rounded-md px-3 py-2 text-sm font-semibold transition ${activeNavPath === item.path
                  ? 'bg-text text-bg'
                  : 'text-text-soft hover:bg-fury-white'
                  }`}
                key={item.path}
                onClick={() => navigate(item.path)}
                type="button"
              >
                {item.label}
              </button>
            ))}
            <a
              className="rounded-md px-3 py-2 text-sm font-semibold text-text-soft transition hover:bg-fury-white"
              href="https://sre.pawjob.us/"
            >
              SRE
            </a>
          </nav>

          <form className="flex min-w-0 gap-2 xl:ml-auto xl:w-[360px]" onSubmit={handleTeamSearch}>
            <input
              className="min-w-0 flex-1 rounded-md border border-border bg-fury-white px-3 py-2 text-sm outline-none transition focus:border-ring focus:shadow-[0_0_0_3px_var(--color-shadow)]"
              placeholder={searchPlaceholder}
              value={teamQuery}
              onChange={(event) => setTeamQuery(event.target.value)}
            />
            <button
              className="rounded-md bg-fury-cyan px-4 py-2 text-sm font-semibold text-text transition hover:bg-fury-aqua"
              type="submit"
            >
              Search
            </button>
          </form>
        </div>
      </header>

      <section className="mx-auto w-full max-w-7xl px-5 sm:px-8">
        {route.page === 'home' ? (
          <Landing live={live} matches={matches} navigate={navigate} />
        ) : null}
        {route.page === 'teams' ? (
          <TeamsPage leaderboard={leaderboard} navigate={navigate} teams={teams} />
        ) : null}
        {route.page === 'team' ? (
          <TeamProfilePage
            navigate={navigate}
            profile={profile}
            requestedTeam={route.teamName}
            teams={teams}
          />
        ) : null}
        {route.page === 'battle-logs' ? <BattleLogsPage live={live} matches={matches} /> : null}
        {route.page === 'uptime' ? <UptimePage uptime={uptime} /> : null}
        {route.page === 'viewers' ? <ViewersPage viewers={viewers} /> : null}
      </section>
      <Footer navigate={navigate} />
      <ConsentBanner consent={analyticsConsent} onChoose={chooseAnalyticsConsent} />
    </main>
  )
}

function Footer({ navigate }) {
  return (
    <footer className="mt-14 border-t border-border bg-fury-white">
      <div className="mx-auto flex w-full max-w-7xl flex-col gap-3 px-5 py-6 text-sm text-text-soft sm:flex-row sm:items-center sm:justify-between sm:px-8">
        <p>Toothless&apos; TSS Bot</p>
        <div className="flex flex-wrap gap-4">
          <button
            className="w-fit font-semibold text-fury-cyan transition hover:text-text"
            onClick={() => navigate('/uptime')}
            type="button"
          >
            Uptime
          </button>
          <button
            className="w-fit font-semibold text-fury-cyan transition hover:text-text"
            onClick={() => navigate('/viewers')}
            type="button"
          >
            viewers
          </button>
        </div>
      </div>
    </footer>
  )
}

function ConsentBanner({ consent, onChoose }) {
  if (consent) {
    return (
      <button
        className="fixed right-4 bottom-4 z-50 rounded-md border border-border bg-fury-white px-3 py-2 text-xs font-semibold text-text-soft shadow-sm transition hover:text-text"
        onClick={() => onChoose('')}
        type="button"
      >
        Privacy settings
      </button>
    )
  }

  return (
    <div className="fixed inset-x-0 bottom-0 z-50 border-t border-border bg-fury-white shadow-[0_-8px_24px_rgba(0,0,0,0.08)]">
      <div className="mx-auto flex w-full max-w-7xl flex-col gap-4 px-5 py-4 sm:px-8 lg:flex-row lg:items-center lg:justify-between">
        <div className="max-w-3xl">
          <h2 className="text-base font-semibold">Analytics consent</h2>
          <p className="mt-1 text-sm text-text-soft">
            We can track page views, live viewing state, browser, device, screen size,
            language, timezone, referrer, and pseudonymous identifiers so the public
            viewers page works. Raw IP addresses are not shown publicly.
          </p>
        </div>
        <div className="flex shrink-0 flex-wrap gap-2">
          <button
            className="rounded-md border border-border px-4 py-2 text-sm font-semibold text-text-soft transition hover:bg-surface hover:text-text"
            onClick={() => onChoose('declined')}
            type="button"
          >
            Decline
          </button>
          <button
            className="rounded-md bg-fury-cyan px-4 py-2 text-sm font-semibold text-bg transition hover:bg-fury-aqua"
            onClick={() => onChoose('analytics')}
            type="button"
          >
            Allow analytics
          </button>
        </div>
      </div>
    </div>
  )
}

function Landing({ live, matches, navigate }) {
  const treeRef = useRef(null)

  return (
    <div className="relative left-1/2 w-screen -translate-x-1/2 bg-bg">
      <div className="relative min-h-[calc(100vh-74px)] overflow-hidden px-5 sm:px-8">
        <PixelMountains />

        <section className="relative z-10 mx-auto grid min-h-[calc(100vh-74px)] w-full max-w-7xl gap-8 pt-16 pb-10 lg:grid-cols-[1.05fr_0.95fr] lg:items-center">
          <div className="max-w-3xl">
            <p className="text-base font-semibold uppercase tracking-wide text-fury-cyan">
              BorisBot got nothin on THIS
            </p>
            <h1 className="mt-3 text-6xl font-bold tracking-normal sm:text-7xl lg:text-8xl">
              Toothless&apos; TSS Bot
            </h1>
            <p className="mt-6 max-w-2xl text-xl leading-9 text-text-soft">
              Powered by Spectra. TSS analytics.
            </p>
            <div className="mt-8 flex flex-wrap gap-4">
              <button
                className="rounded-lg bg-text px-7 py-4 text-base font-semibold text-bg"
                onClick={() => navigate('/teams')}
                type="button"
              >
                Team leaderboard
              </button>
              <button
                className="rounded-lg border-2 border-ring px-7 py-4 text-base font-semibold text-fury-cyan"
                onClick={() => navigate('/battle-logs')}
                type="button"
              >
                Battle Logs
              </button>
            </div>
          </div>

          <div className="relative min-h-[520px] overflow-hidden">
            <FallingLeaves treeRef={treeRef} />
            <div className="absolute inset-0 z-[1] flex items-end justify-center pb-10 lg:pb-0">
              <Tree ref={treeRef} />
            </div>
          </div>
        </section>
      </div>

      <RecentGamesSection live={live} matches={matches} navigate={navigate} />
    </div>
  )
}

function RecentGamesSection({ live, matches, navigate }) {
  const recentMatches = matches.slice(0, 6)

  return (
    <section className="relative z-20 border-t border-border bg-fury-white px-5 py-10 sm:px-8">
      <div className="mx-auto w-full max-w-7xl">
        <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
          <div>
            <p className="text-sm font-semibold uppercase tracking-wide text-fury-cyan">
              Recent activity
            </p>
            <h2 className="mt-1 text-3xl font-bold">Latest games</h2>
          </div>
          <button
            className="w-fit rounded-lg border border-ring px-4 py-2 text-sm font-semibold text-fury-cyan transition hover:bg-surface"
            onClick={() => navigate('/battle-logs')}
            type="button"
          >
            View Battle Logs
          </button>
        </div>

        <div className="mt-6 grid gap-4 lg:grid-cols-3">
          {recentMatches.map((match) => (
            <article
              className="rounded-lg border border-border bg-bg p-4 shadow-sm"
              key={match.session_id}
            >
              <div className="flex items-start justify-between gap-3">
                <div className="min-w-0">
                  <h3 className="truncate text-lg font-semibold">
                    {match.map_name || 'Unknown map'}
                  </h3>
                  <p className="mt-1 text-xs text-text-soft">{formatDate(match.timestamp)}</p>
                </div>
                <span className="shrink-0 rounded-md bg-surface px-2 py-1 text-xs font-semibold text-text-soft">
                  {match.result || 'Unknown'}
                </span>
              </div>

              <div className="mt-4 grid grid-cols-[1fr_auto] items-center gap-3 text-sm">
                <p className="truncate font-semibold text-fury-cyan">
                  {match.team_name || 'TSS team'}
                </p>
                <p className="text-text-soft">
                  {formatNumber(match.player_count)} players
                </p>
              </div>
              <div className="mt-3 flex flex-wrap gap-2 text-xs text-text-soft">
                <span>{formatNumber(match.stats?.ground_kills)} ground</span>
                <span>{formatNumber(match.stats?.air_kills)} air</span>
                <span>{formatNumber(match.stats?.deaths)} deaths</span>
              </div>
            </article>
          ))}
        </div>

        {!recentMatches.length ? (
          <p className="mt-6 rounded-lg border border-border bg-bg px-5 py-6 text-sm text-text-soft">
            {live.status === 'loading' ? 'Loading latest games' : live.error || 'No games returned'}
          </p>
        ) : null}
      </div>
    </section>
  )
}

function PixelMountains() {
  const canvasRef = useRef(null)

  useEffect(() => {
    const canvas = canvasRef.current
    const ctx = canvas.getContext('2d')
    const WORLD_W = 1920
    const WORLD_H = 900

    function interpolate(points, x) {
      for (let i = 0; i < points.length - 1; i++) {
        const [x0, y0] = points[i]
        const [x1, y1] = points[i + 1]
        if (x >= x0 && x <= x1) {
          const t = (x - x0) / Math.max(1, x1 - x0)
          return y0 + (y1 - y0) * t
        }
      }

      return points.at(-1)[1]
    }

    function drawMountain(points, color, jitter = 0) {
      const width = WORLD_W
      const height = WORLD_H
      ctx.fillStyle = color

      for (let x = 0; x < width; x++) {
        const wave = jitter
          ? Math.sin(x * 0.08) * jitter + Math.sin(x * 0.021) * jitter * 1.8
          : 0
        const y = Math.round(interpolate(points, x) + wave)
        ctx.fillRect(x, y, 1, height - y)
      }
    }

    function draw() {
      const width = WORLD_W
      const height = WORLD_H

      canvas.width = WORLD_W
      canvas.height = WORLD_H
      ctx.imageSmoothingEnabled = false
      ctx.clearRect(0, 0, WORLD_W, WORLD_H)

      drawMountain(
        [
          [0, height * 0.82],
          [width * 0.12, height * 0.73],
          [width * 0.26, height * 0.66],
          [width * 0.39, height * 0.76],
          [width * 0.55, height * 0.58],
          [width * 0.64, height * 0.46],
          [width * 0.73, height * 0.62],
          [width * 0.86, height * 0.56],
          [width, height * 0.64],
        ],
        '#fcfbcf',
        1.1,
      )

      drawMountain(
        [
          [0, height * 0.86],
          [width * 0.15, height * 0.78],
          [width * 0.31, height * 0.81],
          [width * 0.43, height * 0.69],
          [width * 0.52, height * 0.76],
          [width * 0.62, height * 0.43],
          [width * 0.69, height * 0.31],
          [width * 0.78, height * 0.48],
          [width, height * 0.5],
        ],
        '#fff2e6',
        1.6,
      )

      drawMountain(
        [
          [0, height * 0.94],
          [width * 0.17, height * 0.9],
          [width * 0.32, height * 0.92],
          [width * 0.47, height * 0.83],
          [width * 0.58, height * 0.89],
          [width * 0.66, height * 0.61],
          [width * 0.71, height * 0.5],
          [width * 0.84, height * 0.7],
          [width, height * 0.68],
        ],
        '#fee5cd',
        2.1,
      )

      drawMountain(
        [
          [0, height * 0.98],
          [width * 0.17, height * 0.96],
          [width * 0.34, height * 0.99],
          [width * 0.48, height * 0.93],
          [width * 0.62, height * 0.97],
          [width * 0.72, height * 0.88],
          [width * 0.86, height * 0.95],
          [width, height * 0.93],
        ],
        '#fdca9b',
        1.4,
      )
    }

    draw()
  }, [])

  return <canvas ref={canvasRef} className="pixel-mountains" aria-hidden="true" />
}

function TeamsPage({ leaderboard, navigate, teams }) {
  return (
    <section className="space-y-6">
      <div>
        <h1 className="text-3xl font-bold">Team leaderboard</h1>
        <p className="mt-2 text-sm text-text-soft">
          {leaderboard.status === 'loading'
            ? 'Loading leaderboard'
            : leaderboard.error || `${teams.length} teams returned`}
        </p>
      </div>

      <div className="overflow-hidden rounded-lg border border-border bg-fury-white shadow-sm">
        {teams.map((team, index) => {
          const name = bestTeamName(team)
          return (
            <button
              className="grid w-full gap-4 border-b border-surface px-5 py-4 text-left hover:bg-surface md:grid-cols-[4rem_1fr_repeat(4,auto)] md:items-center"
              key={`${name}-${team.clan_id || index}`}
              onClick={() => navigate(teamPath(name))}
              type="button"
            >
              <span className="text-sm font-semibold text-fury-cyan">#{index + 1}</span>
              <span className="min-w-0">
                <span className="block truncate text-lg font-semibold">{name}</span>
                <span className="block truncate text-xs text-text-soft">
                  {team.long_name || team.short_name || 'Unresolved'}
                </span>
              </span>
              <span className="text-sm">{formatNumber(team.player_count)} players</span>
              <span className="text-sm">{formatNumber(team.total_battles)} battles</span>
              <span className="text-sm">{Number(team.win_rate || 0).toFixed(1)}% WR</span>
              <span className="text-sm font-semibold">
                {formatNumber(team.points?.total_points || team.total_kills)}
              </span>
            </button>
          )
        })}

        {!teams.length ? (
          <p className="px-5 py-10 text-sm text-text-soft">
            {leaderboard.status === 'loading' ? 'Loading leaderboard' : 'No teams returned'}
          </p>
        ) : null}
      </div>
    </section>
  )
}

function TeamProfilePage({ navigate, profile, requestedTeam, teams }) {
  const detail = profile.detail.data
  const summary = detail?.team_summary || detail?.squadron_summary
  const players = detail?.players || []
  const games = profile.games.data?.games || []
  const history = profile.history.data?.history || []
  const ratingHourly = profile.history.data?.rating_hourly || []
  const latestRating = ratingHourly.at(-1)?.rating || summary?.points?.total_points
  const leaderboardTeam = teams.find((team) => bestTeamName(team) === requestedTeam)
  const displayName = detail?.tag_name || bestTeamName(leaderboardTeam) || requestedTeam
  const longName = detail?.long_name || leaderboardTeam?.long_name || ''

  return (
    <section className="space-y-6">
      <button
        className="text-sm font-semibold text-fury-cyan hover:text-text"
        onClick={() => navigate('/teams')}
        type="button"
      >
        Back to leaderboard
      </button>

      <div className="rounded-lg border border-border bg-fury-white p-6 shadow-sm">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
          <div>
            <p className="text-sm font-semibold uppercase tracking-wide text-fury-cyan">
              Team profile
            </p>
            <h1 className="mt-1 text-4xl font-bold">{displayName}</h1>
            <p className="mt-2 text-sm text-text-soft">
              {profile.detail.error || longName || profile.detail.status}
            </p>
          </div>
          <div className="grid grid-cols-2 gap-3 text-sm sm:grid-cols-3">
            <span className="rounded-md bg-surface px-3 py-2 font-semibold">
              Rating {formatNumber(latestRating)}
            </span>
            <span className="rounded-md bg-surface px-3 py-2 font-semibold">
              Clan {detail?.clan_id || leaderboardTeam?.clan_id || 'n/a'}
            </span>
            <span className="rounded-md bg-surface px-3 py-2 font-semibold">
              {detail?.data_set || 'tss'}
            </span>
          </div>
        </div>

        <div className="mt-6 grid gap-5 sm:grid-cols-2 xl:grid-cols-5">
          <Stat label="Roster" value={formatNumber(summary?.player_count)} />
          <Stat label="Battles" value={formatNumber(summary?.total_battles)} />
          <Stat label="Wins" value={formatNumber(summary?.wins)} />
          <Stat label="Win rate" value={`${Number(summary?.win_rate || 0).toFixed(1)}%`} />
          <Stat label="KDR" value={Number(summary?.kdr || 0).toFixed(1)} />
        </div>
      </div>

      <div className="grid gap-6 xl:grid-cols-[1.15fr_0.85fr]">
        <RosterTable players={players} status={profile.detail.status} />
        <RatingPanel history={history} ratingHourly={ratingHourly} status={profile.history.status} />
      </div>

      <BattleResults games={games} status={profile.games.status} />
    </section>
  )
}

function RosterTable({ players, status }) {
  const sortedPlayers = [...players].sort((a, b) => {
    return (b.total_kills || 0) - (a.total_kills || 0) || String(a.nick || '').localeCompare(b.nick || '')
  })

  return (
    <div className="rounded-lg border border-border bg-fury-white shadow-sm">
      <div className="border-b border-surface px-5 py-4">
        <h2 className="text-lg font-semibold">Roster</h2>
        <p className="mt-1 text-sm text-text-soft">{formatNumber(sortedPlayers.length)} players</p>
      </div>
      <div className="max-h-[520px] overflow-auto">
        {sortedPlayers.map((player) => (
          <div
            className="grid gap-3 border-b border-surface px-5 py-3 text-sm md:grid-cols-[1fr_repeat(5,auto)] md:items-center"
            key={player.uid}
          >
            <div className="min-w-0">
              <p className="truncate font-semibold">{player.nick || player.uid}</p>
              <p className="text-xs text-text-soft">
                {player.uid} · {formatNumber(player.points || player.sqb_points)} pts
              </p>
            </div>
            <p>{formatNumber(player.total_battles)} battles</p>
            <p>{formatNumber(player.total_kills)} kills</p>
            <p>{Number(player.win_rate || 0).toFixed(1)}% WR</p>
            <p>{Number(player.kdr || 0).toFixed(1)} KDR</p>
            <p>{formatNumber(player.assists)} assists</p>
          </div>
        ))}
        {!sortedPlayers.length ? (
          <p className="px-5 py-10 text-sm text-text-soft">
            {status === 'loading' ? 'Loading roster' : 'No roster rows returned'}
          </p>
        ) : null}
      </div>
    </div>
  )
}

function RatingPanel({ history, ratingHourly, status }) {
  const recentHistory = history.slice(-8)
  const firstRating = ratingHourly[0]?.rating || 0
  const latestRating = ratingHourly.at(-1)?.rating || 0
  const ratingChange = latestRating - firstRating

  return (
    <div className="rounded-lg border border-border bg-fury-white shadow-sm">
      <div className="border-b border-surface px-5 py-4">
        <h2 className="text-lg font-semibold">History</h2>
        <p className="mt-1 text-sm text-text-soft">
          {ratingHourly.length ? `${formatNumber(ratingHourly.length)} rating snapshots` : status}
        </p>
      </div>
      <div className="space-y-5 p-5">
        <div className="grid gap-5 sm:grid-cols-2">
          <Stat label="Latest rating" value={formatNumber(latestRating)} />
          <Stat
            label="Rating change"
            value={`${ratingChange >= 0 ? '+' : ''}${formatNumber(ratingChange)}`}
          />
        </div>

        <div className="space-y-2">
          {recentHistory.map((item) => (
            <div
              className="grid grid-cols-[1fr_auto_auto] gap-3 rounded-md bg-surface px-3 py-2 text-sm"
              key={item.period}
            >
              <span className="font-semibold">{item.period}</span>
              <span>{formatNumber(item.battles)} battles</span>
              <span>{Number(item.win_rate || 0).toFixed(1)}% WR</span>
            </div>
          ))}
          {!recentHistory.length ? (
            <p className="text-sm text-text-soft">
              {status === 'loading' ? 'Loading history' : 'No history rows returned'}
            </p>
          ) : null}
        </div>
      </div>
    </div>
  )
}

function BattleResults({ games, status }) {
  return (
    <div className="rounded-lg border border-border bg-fury-white shadow-sm">
      <div className="border-b border-surface px-5 py-4">
        <h2 className="text-lg font-semibold">Battle results</h2>
        <p className="mt-1 text-sm text-text-soft">{formatNumber(games.length)} battles returned</p>
      </div>
      <div className="max-h-[560px] overflow-auto">
        {games.map((game) => (
          <div
            className="grid gap-4 border-b border-surface px-5 py-4 md:grid-cols-[1fr_auto_repeat(5,auto)] md:items-center"
            key={game.session_id}
          >
            <div className="min-w-0">
              <p className="truncate font-semibold">{game.map_name || 'Unknown map'}</p>
              <p className="text-xs text-text-soft">
                {formatDate(game.timestamp)} · {game.session_id}
              </p>
            </div>
            <p
              className={`rounded-md px-3 py-1 text-sm font-semibold ${String(game.result).toLowerCase() === 'win'
                ? 'bg-surface text-fury-cyan'
                : 'bg-fury-ice text-fury-violet'
                }`}
            >
              {game.result || 'Unknown'}
            </p>
            <p className="text-sm">{formatNumber(game.player_count)} players</p>
            <p className="text-sm">{formatNumber(game.stats?.ground_kills)} ground</p>
            <p className="text-sm">{formatNumber(game.stats?.air_kills)} air</p>
            <p className="text-sm">{formatNumber(game.stats?.assists)} assists</p>
            <p className="text-sm">{formatNumber(game.stats?.deaths)} deaths</p>
          </div>
        ))}
        {!games.length ? (
          <p className="px-5 py-10 text-sm text-text-soft">
            {status === 'loading' ? 'Loading battle results' : 'No battle results returned'}
          </p>
        ) : null}
      </div>
    </div>
  )
}

function BattleLogsPage({ live, matches }) {
  return (
    <section className="space-y-6">
      <div>
        <h1 className="text-3xl font-bold">Battle Logs</h1>
        <p className="mt-2 text-sm text-text-soft">
          {live.status === 'loading' ? 'Loading battles' : live.error || `${matches.length} battles returned`}
        </p>
      </div>

      <div className="overflow-hidden rounded-lg border border-border bg-fury-white shadow-sm">
        {matches.map((match) => (
          <div
            className="grid gap-4 border-b border-surface px-5 py-4 md:grid-cols-[1fr_1fr_auto_repeat(4,auto)] md:items-center"
            key={match.session_id}
          >
            <div className="min-w-0">
              <p className="truncate font-semibold">{match.map_name || 'Unknown map'}</p>
              <p className="text-xs text-text-soft">
                {formatDate(match.timestamp)} · {match.session_id}
              </p>
            </div>
            <div className="min-w-0">
              <p className="truncate font-semibold text-fury-cyan">
                {match.team_name || 'TSS team'}
              </p>
              <p className="truncate text-xs text-text-soft">{match.long_name || 'TSS battle record'}</p>
            </div>
            <p
              className={`w-fit rounded-md px-3 py-1 text-sm font-semibold ${String(match.result).toLowerCase() === 'win'
                ? 'bg-surface text-fury-cyan'
                : 'bg-fury-ice text-fury-violet'
                }`}
            >
              {match.result || 'Unknown'}
            </p>
            <p className="text-sm">{formatNumber(match.player_count)} players</p>
            <p className="text-sm">{formatNumber(match.stats?.ground_kills)} ground</p>
            <p className="text-sm">{formatNumber(match.stats?.air_kills)} air</p>
            <p className="text-sm">{formatNumber(match.stats?.deaths)} deaths</p>
          </div>
        ))}

        {!matches.length ? (
          <p className="px-5 py-10 text-sm text-text-soft">
            {live.status === 'loading' ? 'Loading battles' : 'No battles returned'}
          </p>
        ) : null}
      </div>
    </section>
  )
}

function relativeSeconds(timestamp) {
  if (!timestamp) return 'unknown'
  const seconds = Math.max(0, Math.round((Date.now() - new Date(timestamp).getTime()) / 1000))
  if (seconds < 60) return `${seconds}s ago`
  return `${Math.round(seconds / 60)}m ago`
}

function ViewersPage({ viewers }) {
  const data = viewers.data || {}
  const active = data.active || []
  const topPages = data.top_pages || []
  const clients = data.clients || []
  const totals = data.totals || {}
  const generatedAt = data.generated_at ? dateFormat.format(new Date(data.generated_at)) : 'Waiting for data'

  return (
    <section className="space-y-6">
      <div className="rounded-lg border border-border bg-fury-white p-6 shadow-sm">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
          <div>
            <p className="text-sm font-semibold uppercase tracking-wide text-fury-cyan">
              Public analytics
            </p>
            <h1 className="mt-1 text-4xl font-bold">viewers</h1>
            <p className="mt-2 text-sm text-text-soft">
              Live consented browser sessions and page activity. Last refreshed {generatedAt}.
            </p>
          </div>
          <span className="w-fit rounded-md bg-surface px-3 py-2 text-sm font-semibold text-fury-cyan">
            {viewers.status === 'loading' ? 'Loading' : `${formatNumber(totals.active_now)} active now`}
          </span>
        </div>
      </div>

      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
        <Stat label="Active now" value={formatNumber(totals.active_now)} />
        <Stat label="Visitors 24h" value={formatNumber(totals.visitors_24h)} />
        <Stat label="Page views 24h" value={formatNumber(totals.page_views_24h)} />
        <Stat label="Events 24h" value={formatNumber(totals.events_24h)} />
      </div>

      <div className="overflow-hidden rounded-lg border border-border bg-fury-white shadow-sm">
        <div className="border-b border-surface px-5 py-4">
          <h2 className="text-lg font-semibold">Currently viewing</h2>
          <p className="mt-1 text-sm text-text-soft">
            Heartbeats within {formatNumber(data.active_window_seconds || 75)} seconds
          </p>
        </div>
        {active.map((viewer) => (
          <div
            className="grid gap-3 border-b border-surface px-5 py-4 text-sm lg:grid-cols-[1fr_1fr_auto_auto_auto]"
            key={viewer.session}
          >
            <div className="min-w-0">
              <p className="truncate font-semibold">{viewer.page_title || viewer.page_path}</p>
              <p className="truncate text-xs text-text-soft">{viewer.page_path}</p>
            </div>
            <div className="min-w-0">
              <p className="truncate font-semibold">
                {viewer.browser} on {viewer.os}
              </p>
              <p className="truncate text-xs text-text-soft">
                {viewer.device} · {viewer.screen || 'unknown screen'} · {viewer.timezone || 'unknown timezone'}
              </p>
            </div>
            <p className="text-text-soft">{viewer.language || 'unknown language'}</p>
            <p className="text-text-soft">Seen {relativeSeconds(viewer.last_seen_at)}</p>
            <p className="font-mono text-xs text-text-muted">#{viewer.session}</p>
          </div>
        ))}
        {!active.length ? (
          <p className="px-5 py-10 text-sm text-text-soft">
            {viewers.error || 'No consented viewers are active right now'}
          </p>
        ) : null}
      </div>

      <div className="grid gap-6 xl:grid-cols-2">
        <div className="rounded-lg border border-border bg-fury-white shadow-sm">
          <div className="border-b border-surface px-5 py-4">
            <h2 className="text-lg font-semibold">Top pages</h2>
            <p className="mt-1 text-sm text-text-soft">Page views over the last 24 hours</p>
          </div>
          {topPages.map((page) => (
            <div className="grid grid-cols-[1fr_auto] gap-3 border-b border-surface px-5 py-3 text-sm" key={page.page_path}>
              <div className="min-w-0">
                <p className="truncate font-semibold">{page.page_title || page.page_path}</p>
                <p className="truncate text-xs text-text-soft">{page.page_path}</p>
              </div>
              <p className="font-semibold text-fury-cyan">{formatNumber(page.views)}</p>
            </div>
          ))}
          {!topPages.length ? <p className="px-5 py-10 text-sm text-text-soft">No page views recorded yet</p> : null}
        </div>

        <div className="rounded-lg border border-border bg-fury-white shadow-sm">
          <div className="border-b border-surface px-5 py-4">
            <h2 className="text-lg font-semibold">Clients</h2>
            <p className="mt-1 text-sm text-text-soft">Browsers, devices, and operating systems seen in 24 hours</p>
          </div>
          {clients.map((client) => (
            <div
              className="grid grid-cols-[1fr_auto] gap-3 border-b border-surface px-5 py-3 text-sm"
              key={`${client.browser}-${client.os}-${client.device}`}
            >
              <div className="min-w-0">
                <p className="truncate font-semibold">{client.browser} on {client.os}</p>
                <p className="truncate text-xs text-text-soft">{client.device}</p>
              </div>
              <p className="font-semibold text-fury-cyan">{formatNumber(client.events)}</p>
            </div>
          ))}
          {!clients.length ? <p className="px-5 py-10 text-sm text-text-soft">No client data recorded yet</p> : null}
        </div>
      </div>

      <p className="text-xs text-text-soft">
        Analytics are opt-in, retained for {formatNumber(data.privacy?.retention_days || 30)} days,
        and public output excludes raw IP addresses.
      </p>
    </section>
  )
}

function UptimePage({ uptime }) {
  const checks = uptime.checks
  const history = uptime.history
  const operationalCount = checks.filter((check) => check.ok).length
  const allOperational = checks.length > 0 && operationalCount === checks.length
  const updatedAt = uptime.updatedAt ? dateFormat.format(new Date(uptime.updatedAt)) : 'Not checked yet'
  const onlineSamples = history.filter((sample) => sample.ok).length
  const availability = history.length ? (onlineSamples / history.length) * 100 : 0

  return (
    <section className="space-y-6">
      <div className="rounded-lg border border-border bg-fury-white p-6 shadow-sm">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
          <div>
            <p className="text-sm font-semibold uppercase tracking-wide text-fury-cyan">
              Website uptime
            </p>
            <h1 className="mt-1 text-4xl font-bold">
              {allOperational ? 'All systems operational' : 'Status check'}
            </h1>
            <p className="mt-2 text-sm text-text-soft">
              Last server snapshot {updatedAt}. The page refreshes once a minute.
            </p>
          </div>
          <span
            className={`w-fit rounded-md px-3 py-2 text-sm font-semibold ${allOperational
              ? 'bg-surface text-fury-cyan'
              : 'bg-fury-ice text-fury-violet'
              }`}
          >
            {uptime.status === 'loading' ? 'Checking' : `${operationalCount}/${checks.length || 3} online`}
          </span>
        </div>
      </div>

      <div className="rounded-lg border border-border bg-fury-white p-5 shadow-sm">
        <div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
          <div>
            <h2 className="text-lg font-semibold">Availability timeline</h2>
            <p className="mt-1 text-sm text-text-soft">
              Last {formatNumber(history.length)} persisted server snapshots
            </p>
          </div>
          <p className="text-sm font-semibold text-fury-cyan">
            {history.length ? `${availability.toFixed(1)}% uptime` : 'Waiting for first sample'}
          </p>
        </div>

        <div className="mt-5 flex h-28 items-end gap-1 rounded-md border border-border bg-bg p-3">
          {history.map((sample) => {
            const height = `${Math.max(12, (sample.onlineChecks / sample.totalChecks) * 100)}%`

            return (
              <div
                aria-label={`${sample.ok ? 'Uptime' : 'Downtime'} at ${dateFormat.format(new Date(sample.timestamp))}`}
                className={`min-w-2 flex-1 rounded-sm ${sample.ok ? 'bg-success' : 'bg-danger'}`}
                key={sample.timestamp}
                style={{ height }}
                title={`${sample.onlineChecks}/${sample.totalChecks} online`}
              />
            )
          })}

          {!history.length ? (
            <div className="flex h-full w-full items-center justify-center text-sm text-text-soft">
              Checking website status
            </div>
          ) : null}
        </div>

        <div className="mt-3 flex flex-wrap gap-4 text-xs text-text-soft">
          <span className="flex items-center gap-2">
            <span className="h-2.5 w-2.5 rounded-sm bg-success" />
            Uptime
          </span>
          <span className="flex items-center gap-2">
            <span className="h-2.5 w-2.5 rounded-sm bg-danger" />
            Downtime or degraded
          </span>
        </div>
      </div>

      <div className="grid gap-4 lg:grid-cols-3">
        {checks.map((check) => (
          <article className="rounded-lg border border-border bg-fury-white p-5 shadow-sm" key={check.name}>
            <div className="flex items-start justify-between gap-3">
              <div>
                <h2 className="text-lg font-semibold">{check.name}</h2>
                <p className="mt-1 text-sm text-text-soft">{check.detail}</p>
              </div>
              <span
                className={`shrink-0 rounded-md px-2 py-1 text-xs font-semibold ${check.ok
                  ? 'bg-surface text-fury-cyan'
                  : 'bg-fury-ice text-fury-violet'
                  }`}
              >
                {check.ok ? 'Online' : 'Issue'}
              </span>
            </div>
            <p className="mt-5 text-sm font-semibold">{check.label}</p>
            <p className="mt-1 text-xs text-text-soft">{formatNumber(check.latency)} ms response window</p>
          </article>
        ))}

        {!checks.length ? (
          <p className="rounded-lg border border-border bg-fury-white px-5 py-10 text-sm text-text-soft shadow-sm lg:col-span-3">
            Checking website status
          </p>
        ) : null}
      </div>
    </section>
  )
}

export default App
