import { useState, useMemo } from 'react'
import { useParams, Link } from 'react-router-dom'
import styles from './AgentHealth.module.css'

// Layout
import { AppShell } from '../../design-system/layout/AppShell/AppShell'
import { Sidebar } from '../../design-system/layout/Sidebar/Sidebar'
import { TopBar } from '../../design-system/layout/TopBar/TopBar'

// Composites
import { GroupCard } from '../../design-system/composites/GroupCard/GroupCard'
import { LineChart } from '../../design-system/composites/LineChart/LineChart'
import { EventFeed } from '../../design-system/composites/EventFeed/EventFeed'
import { DetailPanel } from '../../design-system/composites/DetailPanel/DetailPanel'

// Primitives
import { StatusDot } from '../../design-system/primitives/StatusDot/StatusDot'
import { MonoText } from '../../design-system/primitives/MonoText/MonoText'
import { Badge } from '../../design-system/primitives/Badge/Badge'
import { StatCard } from '../../design-system/primitives/StatCard/StatCard'
import { ProgressBar } from '../../design-system/primitives/ProgressBar/ProgressBar'

// Global filters
import { useGlobalFilters } from '../../design-system/providers/GlobalFilterProvider'

// Mock data
import { agents, type AgentHealth as AgentHealthData } from '../../mocks/agents'
import { SIDEBAR_APPS } from '../../mocks/sidebar'
import { agentEvents } from '../../mocks/agentEvents'

// ── URL scope parsing ────────────────────────────────────────────────────────

type Scope =
  | { level: 'all' }
  | { level: 'app'; appId: string }

function useScope(): Scope {
  const { '*': rest } = useParams()
  const segments = rest?.split('/').filter(Boolean) ?? []
  if (segments.length >= 1) return { level: 'app', appId: segments[0] }
  return { level: 'all' }
}

// ── Data grouping ────────────────────────────────────────────────────────────

interface AppGroup {
  appId: string
  instances: AgentHealthData[]
  liveCount: number
  staleCount: number
  deadCount: number
  totalTps: number
  totalActiveRoutes: number
  totalRoutes: number
}

function groupByApp(agentList: AgentHealthData[]): AppGroup[] {
  const map = new Map<string, AgentHealthData[]>()
  for (const a of agentList) {
    const list = map.get(a.appId) ?? []
    list.push(a)
    map.set(a.appId, list)
  }
  return Array.from(map.entries()).map(([appId, instances]) => ({
    appId,
    instances,
    liveCount: instances.filter((i) => i.status === 'live').length,
    staleCount: instances.filter((i) => i.status === 'stale').length,
    deadCount: instances.filter((i) => i.status === 'dead').length,
    totalTps: instances.reduce((s, i) => s + i.tps, 0),
    totalActiveRoutes: instances.reduce((s, i) => s + i.activeRoutes, 0),
    totalRoutes: instances.reduce((s, i) => s + i.totalRoutes, 0),
  }))
}

function appHealth(group: AppGroup): 'success' | 'warning' | 'error' {
  if (group.deadCount > 0) return 'error'
  if (group.staleCount > 0) return 'warning'
  return 'success'
}

// ── Trend data (mock) ────────────────────────────────────────────────────────

function buildTrendData(agent: AgentHealthData) {
  const now = Date.now()
  const points = 20
  const interval = (3 * 60 * 60 * 1000) / points

  const throughput = Array.from({ length: points }, (_, i) => ({
    x: new Date(now - (points - i) * interval),
    y: Math.max(0, agent.tps + (Math.random() - 0.5) * 4),
  }))

  const errorRate = Array.from({ length: points }, (_, i) => ({
    x: new Date(now - (points - i) * interval),
    y: Math.max(0, (agent.errorRate ? parseFloat(agent.errorRate) : 0.5) + (Math.random() - 0.5) * 2),
  }))

  return { throughput, errorRate }
}

// ── Breadcrumb ───────────────────────────────────────────────────────────────

function buildBreadcrumb(scope: Scope) {
  const crumbs: { label: string; href?: string }[] = [
    { label: 'Applications', href: '/apps' },
    { label: 'Agents', href: '/agents' },
  ]
  if (scope.level === 'app') {
    crumbs.push({ label: scope.appId })
  }
  return crumbs
}

// ── AgentHealth page ─────────────────────────────────────────────────────────

export function AgentHealth() {
  const scope = useScope()
  const { isInTimeRange } = useGlobalFilters()
  const [selectedInstance, setSelectedInstance] = useState<AgentHealthData | null>(null)
  const [panelOpen, setPanelOpen] = useState(false)

  // Filter agents by scope
  const filteredAgents = useMemo(() => {
    if (scope.level === 'all') return agents
    return agents.filter((a) => a.appId === scope.appId)
  }, [scope])

  const groups = useMemo(() => groupByApp(filteredAgents), [filteredAgents])

  // Aggregate stats
  const totalInstances = filteredAgents.length
  const liveCount = filteredAgents.filter((a) => a.status === 'live').length
  const staleCount = filteredAgents.filter((a) => a.status === 'stale').length
  const deadCount = filteredAgents.filter((a) => a.status === 'dead').length
  const totalTps = filteredAgents.reduce((s, a) => s + a.tps, 0)
  const totalActiveRoutes = filteredAgents.reduce((s, a) => s + a.activeRoutes, 0)
  const totalRoutes = filteredAgents.reduce((s, a) => s + a.totalRoutes, 0)

  // Filter events by global time range
  const filteredEvents = agentEvents.filter((e) => isInTimeRange(e.timestamp))

  // Build trend data for selected instance
  const trendData = selectedInstance ? buildTrendData(selectedInstance) : null

  function handleInstanceClick(inst: AgentHealthData) {
    setSelectedInstance(inst)
    setPanelOpen(true)
  }

  // Detail panel tabs
  const detailTabs = selectedInstance
    ? [
        {
          label: 'Overview',
          value: 'overview',
          content: (
            <div className={styles.detailContent}>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Status</span>
                <Badge
                  label={selectedInstance.status.toUpperCase()}
                  color={selectedInstance.status === 'live' ? 'success' : selectedInstance.status === 'stale' ? 'warning' : 'error'}
                />
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Application</span>
                <MonoText size="xs">{selectedInstance.appId}</MonoText>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Version</span>
                <MonoText size="xs">{selectedInstance.version}</MonoText>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Uptime</span>
                <MonoText size="xs">{selectedInstance.uptime}</MonoText>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Last Seen</span>
                <MonoText size="xs">{selectedInstance.lastSeen}</MonoText>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Throughput</span>
                <MonoText size="xs">{selectedInstance.tps.toFixed(1)}/s</MonoText>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Errors</span>
                <MonoText size="xs" className={selectedInstance.errorRate ? styles.instanceError : undefined}>
                  {selectedInstance.errorRate ?? '0 err/h'}
                </MonoText>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Routes</span>
                <span>{selectedInstance.activeRoutes}/{selectedInstance.totalRoutes} active</span>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>Memory</span>
                <div className={styles.detailProgress}>
                  <ProgressBar
                    value={selectedInstance.memoryUsagePct}
                    variant={selectedInstance.memoryUsagePct > 85 ? 'error' : selectedInstance.memoryUsagePct > 70 ? 'warning' : 'success'}
                  />
                  <MonoText size="xs">{selectedInstance.memoryUsagePct}%</MonoText>
                </div>
              </div>
              <div className={styles.detailRow}>
                <span className={styles.detailLabel}>CPU</span>
                <div className={styles.detailProgress}>
                  <ProgressBar
                    value={selectedInstance.cpuUsagePct}
                    variant={selectedInstance.cpuUsagePct > 85 ? 'error' : selectedInstance.cpuUsagePct > 70 ? 'warning' : 'success'}
                  />
                  <MonoText size="xs">{selectedInstance.cpuUsagePct}%</MonoText>
                </div>
              </div>
            </div>
          ),
        },
        {
          label: 'Performance',
          value: 'performance',
          content: trendData ? (
            <div className={styles.detailContent}>
              <div className={styles.chartPanel}>
                <div className={styles.chartTitle}>Throughput (msg/s)</div>
                <LineChart
                  series={[{ label: 'tps', data: trendData.throughput }]}
                  height={160}
                  width={360}
                  yLabel="msg/s"
                />
              </div>
              <div className={styles.chartPanel}>
                <div className={styles.chartTitle}>Error Rate (err/h)</div>
                <LineChart
                  series={[{ label: 'errors', data: trendData.errorRate, color: 'var(--error)' }]}
                  height={160}
                  width={360}
                  yLabel="err/h"
                />
              </div>
            </div>
          ) : null,
        },
      ]
    : []

  const isFullWidth = scope.level !== 'all'

  return (
    <AppShell
      sidebar={<Sidebar apps={SIDEBAR_APPS} />}
      detail={
        selectedInstance ? (
          <DetailPanel
            open={panelOpen}
            onClose={() => setPanelOpen(false)}
            title={selectedInstance.name}
            tabs={detailTabs}
          />
        ) : undefined
      }
    >
      <TopBar
        breadcrumb={buildBreadcrumb(scope)}
        environment="PRODUCTION"
        user={{ name: 'hendrik' }}
      />

      <div className={styles.content}>
        {/* Stat strip */}
        <div className={styles.statStrip}>
          <StatCard
            label="Total Agents"
            value={String(totalInstances)}
            accent={deadCount > 0 ? 'warning' : 'amber'}
            detail={
              <span className={styles.breakdown}>
                <span className={styles.bpLive}><StatusDot variant="live" /> {liveCount} live</span>
                <span className={styles.bpStale}><StatusDot variant="stale" /> {staleCount} stale</span>
                <span className={styles.bpDead}><StatusDot variant="dead" /> {deadCount} dead</span>
              </span>
            }
          />
          <StatCard
            label="Applications"
            value={String(groups.length)}
            accent="running"
            detail={
              <span className={styles.breakdown}>
                <span className={styles.bpLive}><StatusDot variant="live" /> {groups.filter((g) => g.deadCount === 0 && g.staleCount === 0).length} healthy</span>
                <span className={styles.bpStale}><StatusDot variant="stale" /> {groups.filter((g) => g.staleCount > 0 && g.deadCount === 0).length} degraded</span>
                <span className={styles.bpDead}><StatusDot variant="dead" /> {groups.filter((g) => g.deadCount > 0).length} critical</span>
              </span>
            }
          />
          <StatCard
            label="Active Routes"
            value={<span className={styles[totalActiveRoutes === 0 ? 'routesError' : totalActiveRoutes < totalRoutes ? 'routesWarning' : 'routesSuccess']}>{totalActiveRoutes}/{totalRoutes}</span>}
            accent={totalActiveRoutes === 0 ? 'error' : totalActiveRoutes < totalRoutes ? 'warning' : 'success'}
            detail={totalActiveRoutes < totalRoutes ? `${totalRoutes - totalActiveRoutes} suspended` : 'all routes active'}
          />
          <StatCard
            label="Total TPS"
            value={totalTps.toFixed(1)}
            accent="amber"
            detail="msg/s"
            trend="up"
            trendValue="4.2%"
          />
          <StatCard
            label="Dead"
            value={String(deadCount)}
            accent={deadCount > 0 ? 'error' : 'success'}
            detail={deadCount > 0 ? 'requires attention' : 'all healthy'}
          />
        </div>

        {/* Scope breadcrumb trail */}
        {scope.level !== 'all' && (
          <div className={styles.scopeTrail}>
            <Link to="/agents" className={styles.scopeLink}>All Agents</Link>
            <span className={styles.scopeSep}>&#9656;</span>
            <span className={styles.scopeCurrent}>{scope.appId}</span>
          </div>
        )}

        {/* Section header */}
        <div className={styles.sectionHeaderRow}>
          <span className={styles.sectionTitle}>
            {scope.level === 'all' ? 'Agents' : scope.appId}
          </span>
          <Badge
            label={`${liveCount}/${totalInstances} live`}
            color={deadCount > 0 ? 'error' : staleCount > 0 ? 'warning' : 'success'}
            variant="filled"
          />
        </div>

        {/* Group cards grid */}
        <div className={isFullWidth ? styles.groupGridSingle : styles.groupGrid}>
          {groups.map((group) => (
            <GroupCard
              key={group.appId}
              title={group.appId}
              accent={appHealth(group)}
              headerRight={
                <Badge
                  label={`${group.liveCount}/${group.instances.length} LIVE`}
                  color={appHealth(group)}
                  variant="filled"
                />
              }
              meta={
                <div className={styles.groupMeta}>
                  <span><strong>{group.totalTps.toFixed(1)}</strong> msg/s</span>
                  <span><strong>{group.totalActiveRoutes}</strong>/{group.totalRoutes} routes</span>
                  <span>
                    <StatusDot variant={appHealth(group) === 'success' ? 'live' : appHealth(group) === 'warning' ? 'stale' : 'dead'} />
                  </span>
                </div>
              }
              footer={group.deadCount > 0 ? (
                <div className={styles.alertBanner}>
                  <span className={styles.alertIcon}>&#9888;</span>
                  <span>Single point of failure — {group.deadCount === group.instances.length ? 'no redundancy' : `${group.deadCount} dead instance${group.deadCount > 1 ? 's' : ''}`}</span>
                </div>
              ) : undefined}
            >
              <table className={styles.instanceTable}>
                <thead>
                  <tr>
                    <th className={styles.thStatus} />
                    <th>Instance</th>
                    <th>State</th>
                    <th>Uptime</th>
                    <th>TPS</th>
                    <th>Errors</th>
                    <th>Heartbeat</th>
                  </tr>
                </thead>
                <tbody>
                  {group.instances.map((inst) => (
                    <tr
                      key={inst.id}
                      className={[
                        styles.instanceRow,
                        selectedInstance?.id === inst.id && panelOpen ? styles.instanceRowActive : '',
                      ].filter(Boolean).join(' ')}
                      onClick={() => handleInstanceClick(inst)}
                    >
                      <td className={styles.tdStatus}>
                        <StatusDot variant={inst.status === 'live' ? 'live' : inst.status === 'stale' ? 'stale' : 'dead'} />
                      </td>
                      <td>
                        <MonoText size="sm" className={styles.instanceName}>{inst.name}</MonoText>
                      </td>
                      <td>
                        <Badge
                          label={inst.status.toUpperCase()}
                          color={inst.status === 'live' ? 'success' : inst.status === 'stale' ? 'warning' : 'error'}
                          variant="filled"
                        />
                      </td>
                      <td>
                        <MonoText size="xs" className={styles.instanceMeta}>{inst.uptime}</MonoText>
                      </td>
                      <td>
                        <MonoText size="xs" className={styles.instanceMeta}>{inst.tps.toFixed(1)}/s</MonoText>
                      </td>
                      <td>
                        <MonoText size="xs" className={inst.errorRate ? styles.instanceError : styles.instanceMeta}>
                          {inst.errorRate ?? '0 err/h'}
                        </MonoText>
                      </td>
                      <td>
                        <MonoText size="xs" className={
                          inst.status === 'dead' ? styles.instanceHeartbeatDead :
                          inst.status === 'stale' ? styles.instanceHeartbeatStale :
                          styles.instanceMeta
                        }>
                          {inst.lastSeen}
                        </MonoText>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </GroupCard>
          ))}
        </div>

        {/* EventFeed */}
        {filteredEvents.length > 0 && (
          <div className={styles.eventCard}>
            <div className={styles.eventCardHeader}>
              <span className={styles.sectionTitle}>Timeline</span>
              <span className={styles.sectionMeta}>{filteredEvents.length} events</span>
            </div>
            <EventFeed events={filteredEvents} />
          </div>
        )}
      </div>
    </AppShell>
  )
}
