import { useMemo } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { AlertTriangle } from 'lucide-react'
import styles from './RouteDetail.module.css'

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

// Composites
import { ProcessorTimeline } from '../../design-system/composites/ProcessorTimeline/ProcessorTimeline'
import { DataTable } from '../../design-system/composites/DataTable/DataTable'
import type { Column } from '../../design-system/composites/DataTable/types'

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

// Utils
import { formatDuration, statusToVariant, statusLabel, formatTimestamp, durationClass } from '../../utils/format-utils'

// Mock data
import { routes } from '../../mocks/routes'
import { exchanges, type Exchange } from '../../mocks/exchanges'

// ─── Helpers ──────────────────────────────────────────────────────────────────
function routeStatusVariant(status: 'healthy' | 'degraded' | 'down'): 'success' | 'warning' | 'error' {
  switch (status) {
    case 'healthy': return 'success'
    case 'degraded': return 'warning'
    case 'down': return 'error'
  }
}

// ─── Columns for exchanges table ────────────────────────────────────────────
const EXCHANGE_COLUMNS: Column<Exchange>[] = [
  {
    key: 'status',
    header: 'Status',
    width: '80px',
    render: (_, row) => (
      <span className={styles.statusCell}>
        <StatusDot variant={statusToVariant(row.status)} />
        <MonoText size="xs">{statusLabel(row.status)}</MonoText>
      </span>
    ),
  },
  {
    key: 'id',
    header: 'Exchange ID',
    render: (_, row) => <MonoText size="xs">{row.id}</MonoText>,
  },
  {
    key: 'orderId',
    header: 'Order ID',
    sortable: true,
    render: (_, row) => <MonoText size="sm">{row.orderId}</MonoText>,
  },
  {
    key: 'customer',
    header: 'Customer',
    render: (_, row) => <MonoText size="xs" className={styles.customerText}>{row.customer}</MonoText>,
  },
  {
    key: 'timestamp',
    header: 'Started',
    sortable: true,
    render: (_, row) => <MonoText size="xs">{formatTimestamp(row.timestamp)}</MonoText>,
  },
  {
    key: 'durationMs',
    header: 'Duration',
    sortable: true,
    render: (_, row) => (
      <MonoText size="sm" className={durationClass(row.durationMs, row.status, styles)}>
        {formatDuration(row.durationMs)}
      </MonoText>
    ),
  },
  {
    key: 'agent',
    header: 'Agent',
    render: (_, row) => (
      <span className={styles.agentBadge}>
        <span className={styles.agentDot} />
        {row.agent}
      </span>
    ),
  },
]

// ─── RouteDetail component ────────────────────────────────────────────────────
export function RouteDetail() {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()

  const route = useMemo(() => routes.find((r) => r.id === id), [id])
  const routeExchanges = useMemo(
    () => exchanges.filter((e) => e.route === id),
    [id],
  )

  // Error patterns grouped by exception class
  const errorPatterns = useMemo(() => {
    const patterns: Record<string, { count: number; lastMessage: string; lastTime: Date }> = {}
    for (const exec of routeExchanges) {
      if (exec.status === 'failed' && exec.errorClass) {
        if (!patterns[exec.errorClass]) {
          patterns[exec.errorClass] = {
            count: 0,
            lastMessage: exec.errorMessage ?? '',
            lastTime: exec.timestamp,
          }
        }
        patterns[exec.errorClass].count++
        if (exec.timestamp > patterns[exec.errorClass].lastTime) {
          patterns[exec.errorClass].lastTime = exec.timestamp
          patterns[exec.errorClass].lastMessage = exec.errorMessage ?? ''
        }
      }
    }
    return Object.entries(patterns)
  }, [routeExchanges])

  // Build aggregate processor timeline from all exchanges for this route
  const aggregateProcessors = useMemo(() => {
    if (routeExchanges.length === 0) return []
    // Use the first exchange's processors as the template, with averaged durations
    const templateExec = routeExchanges[0]
    if (!templateExec) return []
    return templateExec.processors.map((proc) => {
      const allDurations = routeExchanges
        .flatMap((e) => e.processors)
        .filter((p) => p.name === proc.name)
        .map((p) => p.durationMs)
      const avgDuration = allDurations.length
        ? Math.round(allDurations.reduce((a, b) => a + b, 0) / allDurations.length)
        : proc.durationMs
      const hasFailures = routeExchanges.some((e) =>
        e.processors.some((p) => p.name === proc.name && p.status === 'fail'),
      )
      const hasSlows = routeExchanges.some((e) =>
        e.processors.some((p) => p.name === proc.name && p.status === 'slow'),
      )
      return {
        ...proc,
        durationMs: avgDuration,
        status: hasFailures ? ('fail' as const) : hasSlows ? ('slow' as const) : ('ok' as const),
      }
    })
  }, [routeExchanges])

  const totalAggregateMs = aggregateProcessors.reduce((sum, p) => sum + p.durationMs, 0)

  const inflightCount = routeExchanges.filter((e) => e.status === 'running').length
  const successCount = routeExchanges.filter((e) => e.status === 'completed').length
  const errorCount = routeExchanges.filter((e) => e.status === 'failed').length
  const successRate = routeExchanges.length
    ? ((successCount / routeExchanges.length) * 100).toFixed(1)
    : '0.0'

  // Not found state
  if (!route) {
    return (
      <>
        <TopBar
          breadcrumb={[
            { label: 'Applications', href: '/apps' },
            { label: 'Routes' },
            { label: id ?? 'Unknown' },
          ]}
          environment="PRODUCTION"
          user={{ name: 'hendrik' }}
        />
        <div className={styles.content}>
          <InfoCallout variant="warning">Route "{id}" not found in mock data.</InfoCallout>
        </div>
      </>
    )
  }

  const statusVariant = routeStatusVariant(route.status)

  return (
    <>
      {/* Top bar */}
      <TopBar
        breadcrumb={[
          { label: 'Applications', href: '/apps' },
          { label: 'Routes', href: '/apps' },
          { label: route.name },
        ]}
        environment="PRODUCTION"

        user={{ name: 'hendrik' }}
      />

      {/* Scrollable content */}
      <div className={styles.content}>

        {/* Route header card */}
        <div className={styles.routeHeader}>
          <div className={styles.routeTitleRow}>
            <div className={styles.routeTitleGroup}>
              <StatusDot variant={statusVariant} />
              <h1 className={styles.routeName}>{route.name}</h1>
              <Badge
                label={route.status.toUpperCase()}
                color={statusVariant}
                variant="filled"
              />
            </div>
            <div className={styles.routeMeta}>
              <span className={styles.routeGroup}>{route.group}</span>
            </div>
          </div>
          <p className={styles.routeDescription}>{route.description}</p>
        </div>

        {/* KPI strip */}
        <div className={styles.kpiStrip}>
          <div className={styles.kpiCard}>
            <div className={styles.kpiLabel}>Total Exchanges</div>
            <div className={styles.kpiValue}>{route.exchangeCount.toLocaleString()}</div>
          </div>
          <div className={styles.kpiCard}>
            <div className={styles.kpiLabel}>Success Rate</div>
            <div className={`${styles.kpiValue} ${
              route.successRate >= 99 ? styles.kpiGood : route.successRate >= 97 ? styles.kpiWarn : styles.kpiError
            }`}>
              {route.successRate}%
            </div>
          </div>
          <div className={styles.kpiCard}>
            <div className={styles.kpiLabel}>Avg Latency (p50)</div>
            <div className={styles.kpiValue}>{route.avgDurationMs}ms</div>
          </div>
          <div className={styles.kpiCard}>
            <div className={styles.kpiLabel}>p99 Latency</div>
            <div className={`${styles.kpiValue} ${route.p99DurationMs > 300 ? styles.kpiError : route.p99DurationMs > 200 ? styles.kpiWarn : styles.kpiGood}`}>
              {route.p99DurationMs}ms
            </div>
          </div>
          <div className={styles.kpiCard}>
            <div className={styles.kpiLabel}>Inflight</div>
            <div className={`${styles.kpiValue} ${inflightCount > 0 ? styles.kpiRunning : ''}`}>
              {inflightCount}
            </div>
          </div>
        </div>

        {/* Processor timeline (aggregate view) */}
        <div className={styles.section}>
          <div className={styles.sectionHeader}>
            <span className={styles.sectionTitle}>Processor Performance (aggregate avg)</span>
            <span className={styles.sectionMeta}>Based on {routeExchanges.length} exchanges</span>
          </div>
          {aggregateProcessors.length > 0 ? (
            <ProcessorTimeline
              processors={aggregateProcessors}
              totalMs={totalAggregateMs}
            />
          ) : (
            <div className={styles.emptyMsg}>No exchange data for this route in mock set.</div>
          )}
        </div>

        {/* Recent exchanges table */}
        <div className={styles.tableSection}>
          <div className={styles.tableHeader}>
            <span className={styles.tableTitle}>Recent Exchanges</span>
            <div className={styles.tableRight}>
              <span className={styles.tableMeta}>
                {routeExchanges.length} exchanges · {errorCount} errors
              </span>
              <Badge
                label={`${successRate}% ok`}
                color={parseFloat(successRate) >= 99 ? 'success' : parseFloat(successRate) >= 97 ? 'warning' : 'error'}
              />
            </div>
          </div>
          <DataTable
            columns={EXCHANGE_COLUMNS}
            data={routeExchanges}
            sortable
            flush
            rowAccent={(row) => {
              if (row.status === 'failed') return 'error'
              if (row.status === 'warning') return 'warning'
              return undefined
            }}
            expandedContent={(row) =>
              row.errorMessage ? (
                <div className={styles.inlineError}>
                  <span className={styles.inlineErrorIcon}><AlertTriangle size={14} /></span>
                  <div>
                    <div className={styles.errorClass}>{row.errorClass}</div>
                    <div className={styles.errorText}>{row.errorMessage}</div>
                  </div>
                </div>
              ) : null
            }
            onRowClick={(row) => navigate(`/exchanges/${row.id}`)}
          />
        </div>

        {/* Error patterns section */}
        {errorPatterns.length > 0 && (
          <div className={styles.section}>
            <div className={styles.sectionHeader}>
              <span className={styles.sectionTitle}>Error Patterns</span>
              <span className={styles.sectionMeta}>{errorPatterns.length} distinct exception types</span>
            </div>
            <div className={styles.errorPatterns}>
              {errorPatterns.map(([cls, info]) => (
                <div key={cls} className={styles.errorPattern}>
                  <div className={styles.errorPatternHeader}>
                    <MonoText size="xs" className={styles.errorClass}>{cls}</MonoText>
                    <Badge label={`${info.count}x`} color="error" />
                  </div>
                  <div className={styles.errorPatternMessage}>{info.lastMessage}</div>
                  <div className={styles.errorPatternTime}>
                    Last seen: {formatTimestamp(info.lastTime)}
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

      </div>
    </>
  )
}
