import { useMemo } from 'react'
import { useParams, Link } from 'react-router-dom'
import { ChevronRight } from 'lucide-react'
import styles from './AgentInstance.module.css'

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

// Composites
import { LineChart } from '../../design-system/composites/LineChart/LineChart'
import { AreaChart } from '../../design-system/composites/AreaChart/AreaChart'
import { EventFeed } from '../../design-system/composites/EventFeed/EventFeed'
import { Tabs } from '../../design-system/composites/Tabs/Tabs'
import { LogViewer } from '../../design-system/composites/LogViewer/LogViewer'
import type { LogEntry } from '../../design-system/composites/LogViewer/LogViewer'

// 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 { SectionHeader } from '../../design-system/primitives/SectionHeader/SectionHeader'

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

// Data
import { agents } from '../../mocks/agents'
import { agentEvents } from '../../mocks/agentEvents'

import { useState } from 'react'

// ── Mock trend data ──────────────────────────────────────────────────────────

function buildTimeSeries(baseValue: number, variance: number, points = 30) {
  const now = Date.now()
  const interval = (6 * 60 * 60 * 1000) / points
  return Array.from({ length: points }, (_, i) => ({
    x: new Date(now - (points - i) * interval),
    y: Math.max(0, baseValue + (Math.random() - 0.5) * variance * 2),
  }))
}

function buildMemoryHistory(currentPct: number) {
  return [
    { label: 'Heap Used', data: buildTimeSeries(currentPct * 0.7, 10) },
    { label: 'Heap Total', data: buildTimeSeries(currentPct * 0.9, 5) },
  ]
}

// ── Mock log entries ─────────────────────────────────────────────────────────

function buildLogEntries(agentName: string): LogEntry[] {
  const now = Date.now()
  const MIN = 60_000
  return [
    { timestamp: new Date(now - 1 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.DefaultCamelContext] Route order-validation started and consuming from: direct:validate` },
    { timestamp: new Date(now - 2 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.DefaultCamelContext] Total 3 routes, of which 3 are started` },
    { timestamp: new Date(now - 5 * MIN).toISOString(), level: 'warn', message: `[o.a.c.processor.errorhandler] Failed delivery for exchangeId: ID-${agentName}-1710847200000-0-1. Exhausted after 3 attempts.` },
    { timestamp: new Date(now - 8 * MIN).toISOString(), level: 'info', message: `[o.a.c.health.HealthCheckHelper] Health check [routes] is UP` },
    { timestamp: new Date(now - 12 * MIN).toISOString(), level: 'info', message: `[o.a.c.health.HealthCheckHelper] Health check [consumers] is UP` },
    { timestamp: new Date(now - 15 * MIN).toISOString(), level: 'debug', message: `[o.a.c.component.kafka] KafkaConsumer[order-events] poll returned 42 records in 18ms` },
    { timestamp: new Date(now - 18 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.engine.InternalRouteStartup] Route order-enrichment started and consuming from: kafka:order-events` },
    { timestamp: new Date(now - 25 * MIN).toISOString(), level: 'warn', message: `[o.a.c.component.http] HTTP endpoint https://payment-api.internal/verify returned 503 — will retry` },
    { timestamp: new Date(now - 30 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.DefaultCamelContext] Apache Camel ${agentName} (CamelContext) is starting` },
    { timestamp: new Date(now - 32 * MIN).toISOString(), level: 'info', message: `[org.springframework.boot] Started ${agentName} in 4.231 seconds (process running for 4.892)` },
  ]
}

// ── Mock JVM / process info ──────────────────────────────────────────────────

function buildProcessInfo(agent: typeof agents[0]) {
  return {
    jvmVersion: 'OpenJDK 21.0.2+13',
    camelVersion: '4.4.0',
    springBootVersion: '3.2.4',
    pid: Math.floor(1000 + Math.random() * 90000),
    startTime: new Date(Date.now() - parseDuration(agent.uptime)).toISOString(),
    heapMax: '512 MB',
    heapUsed: `${Math.round(512 * agent.memoryUsagePct / 100)} MB`,
    nonHeapUsed: `${Math.round(80 + Math.random() * 40)} MB`,
    threadCount: Math.floor(20 + Math.random() * 30),
    peakThreads: Math.floor(45 + Math.random() * 20),
    gcCollections: Math.floor(Math.random() * 500),
    gcPauseTotal: `${(Math.random() * 2).toFixed(2)}s`,
    classesLoaded: Math.floor(8000 + Math.random() * 4000),
    openFileDescriptors: Math.floor(50 + Math.random() * 200),
    maxFileDescriptors: 65536,
  }
}

function parseDuration(s: string): number {
  let ms = 0
  const dMatch = s.match(/(\d+)d/)
  const hMatch = s.match(/(\d+)h/)
  const mMatch = s.match(/(\d+)m/)
  if (dMatch) ms += parseInt(dMatch[1]) * 86400000
  if (hMatch) ms += parseInt(hMatch[1]) * 3600000
  if (mMatch) ms += parseInt(mMatch[1]) * 60000
  return ms || 60000
}

// ── Component ────────────────────────────────────────────────────────────────

const LOG_TABS = [
  { label: 'All', value: 'all' },
  { label: 'Warnings', value: 'warn' },
  { label: 'Errors', value: 'error' },
]

export function AgentInstance() {
  const { appId, instanceId } = useParams<{ appId: string; instanceId: string }>()
  const { isInTimeRange } = useGlobalFilters()
  const [logFilter, setLogFilter] = useState('all')

  const agent = agents.find((a) => a.appId === appId && a.id === instanceId)

  const instanceEvents = useMemo(() => {
    if (!agent) return []
    return agentEvents
      .filter((e) => e.searchText?.toLowerCase().includes(agent.name.toLowerCase()))
      .filter((e) => isInTimeRange(e.timestamp))
  }, [agent, isInTimeRange])

  if (!agent) {
    return (
      <>
        <TopBar breadcrumb={[{ label: 'Agents', href: '/agents' }, { label: 'Not Found' }]} environment="PRODUCTION" user={{ name: 'hendrik' }} />
        <div className={styles.content}>
          <div className={styles.notFound}>Agent instance not found.</div>
        </div>
      </>
    )
  }

  const processInfo = buildProcessInfo(agent)
  const logEntries = buildLogEntries(agent.name)
  const filteredLogs = logFilter === 'all'
    ? logEntries
    : logEntries.filter((l) => l.level === logFilter)

  const cpuData = buildTimeSeries(agent.cpuUsagePct, 15)
  const memSeries = buildMemoryHistory(agent.memoryUsagePct)
  const tpsSeries = [{ label: 'Throughput', data: buildTimeSeries(agent.tps, 5) }]
  const errorSeries = [{ label: 'Errors', data: buildTimeSeries(agent.errorRate ? parseFloat(agent.errorRate) : 0.2, 2), color: 'var(--error)' }]
  const threadSeries = [{ label: 'Threads', data: buildTimeSeries(processInfo.threadCount, 8) }]
  const gcSeries = [{ label: 'GC Pause', data: buildTimeSeries(4, 6) }]

  const statusVariant = agent.status === 'live' ? 'live' : agent.status === 'stale' ? 'stale' : 'dead'
  const statusColor = agent.status === 'live' ? 'success' : agent.status === 'stale' ? 'warning' : 'error'

  return (
    <>
      <TopBar
        breadcrumb={[
          { label: 'Applications', href: '/apps' },
          { label: 'Agents', href: '/agents' },
          { label: appId!, href: `/agents/${appId}` },
          { label: instanceId! },
        ]}
        environment="PRODUCTION"
        user={{ name: 'hendrik' }}
      />

      <div className={styles.content}>
        {/* Stat strip — 5 columns matching /agents */}
        <div className={styles.statStrip}>
          <StatCard label="CPU" value={`${agent.cpuUsagePct}%`} accent={agent.cpuUsagePct > 85 ? 'error' : agent.cpuUsagePct > 70 ? 'warning' : 'success'} />
          <StatCard label="Memory" value={`${agent.memoryUsagePct}%`} accent={agent.memoryUsagePct > 85 ? 'error' : agent.memoryUsagePct > 70 ? 'warning' : 'success'} detail={`${processInfo.heapUsed} / ${processInfo.heapMax}`} />
          <StatCard label="Throughput" value={`${agent.tps.toFixed(1)}/s`} accent="amber" detail="msg/s" />
          <StatCard label="Errors" value={agent.errorRate ?? '0 err/h'} accent={agent.errorRate ? 'error' : 'success'} />
          <StatCard label="Uptime" value={agent.uptime || '—'} accent="running" detail={`since ${new Date(processInfo.startTime).toLocaleDateString()}`} />
        </div>

        {/* Scope trail + badges */}
        <div className={styles.scopeTrail}>
          <Link to="/agents" className={styles.scopeLink}>All Agents</Link>
          <span className={styles.scopeSep}><ChevronRight size={12} /></span>
          <Link to={`/agents/${appId}`} className={styles.scopeLink}>{appId}</Link>
          <span className={styles.scopeSep}><ChevronRight size={12} /></span>
          <span className={styles.scopeCurrent}>{agent.name}</span>
          <Badge label={agent.status.toUpperCase()} color={statusColor} />
          <Badge label={agent.version} color="auto" variant="outlined" />
          <Badge label={`${agent.activeRoutes}/${agent.totalRoutes} routes`} color={agent.activeRoutes < agent.totalRoutes ? 'warning' : 'success'} />
        </div>

        {/* Process info card — right below stat strip */}
        <div className={styles.processCard}>
          <SectionHeader>Process Information</SectionHeader>
          <div className={styles.processGrid}>
            <span className={styles.processLabel}>JVM</span>
            <MonoText size="xs">{processInfo.jvmVersion}</MonoText>

            <span className={styles.processLabel}>Camel</span>
            <MonoText size="xs">{processInfo.camelVersion}</MonoText>

            <span className={styles.processLabel}>Spring Boot</span>
            <MonoText size="xs">{processInfo.springBootVersion}</MonoText>

            <span className={styles.processLabel}>Started</span>
            <MonoText size="xs">{new Date(processInfo.startTime).toLocaleString()}</MonoText>

            <span className={styles.processLabel}>File Descriptors</span>
            <MonoText size="xs">{processInfo.openFileDescriptors} / {processInfo.maxFileDescriptors.toLocaleString()}</MonoText>
          </div>
        </div>

        {/* Charts grid — 3x2 (CPU, Memory, Throughput, Errors, Threads, GC) */}
        <div className={styles.chartsGrid}>
          <div className={styles.chartCard}>
            <div className={styles.chartHeader}>
              <span className={styles.chartTitle}>CPU Usage</span>
              <span className={styles.chartMeta}>{agent.cpuUsagePct}% current</span>
            </div>
            <AreaChart
              series={[{ label: 'CPU %', data: cpuData }]}
              height={160}
              yLabel="%"
              thresholdValue={85}
              thresholdLabel="Alert"
            />
          </div>

          <div className={styles.chartCard}>
            <div className={styles.chartHeader}>
              <span className={styles.chartTitle}>Memory (Heap)</span>
              <span className={styles.chartMeta}>{processInfo.heapUsed} / {processInfo.heapMax}</span>
            </div>
            <AreaChart
              series={memSeries}
              height={160}
              yLabel="MB"
            />
          </div>

          <div className={styles.chartCard}>
            <div className={styles.chartHeader}>
              <span className={styles.chartTitle}>Throughput</span>
              <span className={styles.chartMeta}>{agent.tps.toFixed(1)} msg/s</span>
            </div>
            <LineChart
              series={tpsSeries}
              height={160}
              yLabel="msg/s"
            />
          </div>

          <div className={styles.chartCard}>
            <div className={styles.chartHeader}>
              <span className={styles.chartTitle}>Error Rate</span>
              <span className={styles.chartMeta}>{agent.errorRate ?? '0 err/h'}</span>
            </div>
            <LineChart
              series={errorSeries}
              height={160}
              yLabel="err/h"
            />
          </div>

          <div className={styles.chartCard}>
            <div className={styles.chartHeader}>
              <span className={styles.chartTitle}>Thread Count</span>
              <span className={styles.chartMeta}>{processInfo.threadCount} active</span>
            </div>
            <LineChart series={threadSeries} height={160} yLabel="threads" />
          </div>

          <div className={styles.chartCard}>
            <div className={styles.chartHeader}>
              <span className={styles.chartTitle}>GC Pauses</span>
              <span className={styles.chartMeta}>{processInfo.gcPauseTotal} total</span>
            </div>
            <LineChart series={gcSeries} height={160} yLabel="ms" />
          </div>
        </div>

        {/* Log + Timeline side by side */}
        <div className={styles.bottomRow}>
          {/* Log viewer */}
          <div className={styles.logCard}>
            <div className={styles.logHeader}>
              <SectionHeader>Application Log</SectionHeader>
              <Tabs tabs={LOG_TABS} active={logFilter} onChange={setLogFilter} />
            </div>
            <LogViewer entries={filteredLogs} maxHeight={360} />
          </div>

          {/* Timeline */}
          <div className={styles.timelineCard}>
            <div className={styles.timelineHeader}>
              <span className={styles.chartTitle}>Timeline</span>
              <span className={styles.chartMeta}>{instanceEvents.length} events</span>
            </div>
            {instanceEvents.length > 0 ? (
              <EventFeed events={instanceEvents} />
            ) : (
              <div className={styles.logEmpty}>No events in the selected time range.</div>
            )}
          </div>
        </div>
      </div>
    </>
  )
}
