import { useState, useMemo } from 'react'
import { useParams } from 'react-router-dom'
import styles from './Dashboard.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 { DataTable } from '../../design-system/composites/DataTable/DataTable'
import type { Column } from '../../design-system/composites/DataTable/types'
import { DetailPanel } from '../../design-system/composites/DetailPanel/DetailPanel'
import { ShortcutsBar } from '../../design-system/composites/ShortcutsBar/ShortcutsBar'
import { ProcessorTimeline } from '../../design-system/composites/ProcessorTimeline/ProcessorTimeline'

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

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

// Mock data
import { exchanges, type Exchange } from '../../mocks/exchanges'
import { kpiMetrics } from '../../mocks/metrics'
import { SIDEBAR_APPS } from '../../mocks/sidebar'

// ─── Helpers ─────────────────────────────────────────────────────────────────
function formatDuration(ms: number): string {
  if (ms >= 60_000) return `${(ms / 1000).toFixed(0)}s`
  if (ms >= 1000) return `${(ms / 1000).toFixed(2)}s`
  return `${ms}ms`
}

function formatTimestamp(date: Date): string {
  return date.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit' })
}

function statusToVariant(status: Exchange['status']): 'success' | 'error' | 'running' | 'warning' {
  switch (status) {
    case 'completed': return 'success'
    case 'failed': return 'error'
    case 'running': return 'running'
    case 'warning': return 'warning'
  }
}

function statusLabel(status: Exchange['status']): string {
  switch (status) {
    case 'completed': return 'OK'
    case 'failed': return 'ERR'
    case 'running': return 'RUN'
    case 'warning': return 'WARN'
  }
}

// ─── Table columns ────────────────────────────────────────────────────────────
const 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: 'route',
    header: 'Route',
    sortable: true,
    render: (_, row) => (
      <div>
        <div className={styles.routeName}>{row.route}</div>
        <div className={styles.routeGroup}>{row.routeGroup}</div>
      </div>
    ),
  },
  {
    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)}>
        {formatDuration(row.durationMs)}
      </MonoText>
    ),
  },
  {
    key: 'agent',
    header: 'Agent',
    render: (_, row) => (
      <span className={styles.agentBadge}>
        <span className={styles.agentDot} />
        {row.agent}
      </span>
    ),
  },
]

function durationClass(ms: number, status: Exchange['status']): string {
  if (status === 'failed') return styles.durBreach
  if (ms < 100) return styles.durFast
  if (ms < 200) return styles.durNormal
  if (ms < 300) return styles.durSlow
  return styles.durBreach
}

const SHORTCUTS = [
  { keys: 'Ctrl+K', label: 'Search' },
  { keys: '↑↓', label: 'Navigate rows' },
  { keys: 'Enter', label: 'Open detail' },
  { keys: 'Esc', label: 'Close panel' },
]

// ─── Dashboard component ──────────────────────────────────────────────────────
export function Dashboard() {
  const { id: appId } = useParams<{ id: string }>()
  const [selectedId, setSelectedId] = useState<string | undefined>()
  const [panelOpen, setPanelOpen] = useState(false)
  const [selectedExchange, setSelectedExchange] = useState<Exchange | null>(null)

  const { isInTimeRange, statusFilters } = useGlobalFilters()

  // Build set of route IDs belonging to the selected app (if any)
  const appRouteIds = useMemo(() => {
    if (!appId) return null
    const app = SIDEBAR_APPS.find((a) => a.id === appId)
    if (!app) return null
    return new Set(app.routes.map((r) => r.id))
  }, [appId])

  // Scope all data to the selected app
  const scopedExchanges = useMemo(() => {
    if (!appRouteIds) return exchanges
    return exchanges.filter((e) => appRouteIds.has(e.route))
  }, [appRouteIds])

  // Filter exchanges (scoped + global filters)
  const filteredExchanges = useMemo(() => {
    let data = scopedExchanges

    // Time range filter
    data = data.filter((e) => isInTimeRange(e.timestamp))

    // Status filter
    if (statusFilters.size > 0) {
      data = data.filter((e) => statusFilters.has(e.status))
    }

    return data
  }, [scopedExchanges, isInTimeRange, statusFilters])

  function handleRowClick(row: Exchange) {
    setSelectedId(row.id)
    setSelectedExchange(row)
    setPanelOpen(true)
  }

  function handleRowAccent(row: Exchange): 'error' | 'warning' | undefined {
    if (row.status === 'failed') return 'error'
    if (row.status === 'warning') return 'warning'
    return undefined
  }

  // Build detail panel tabs for selected exchange
  const detailTabs = selectedExchange
    ? [
        {
          label: 'Overview',
          value: 'overview',
          content: (
            <div className={styles.overviewTab}>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Order ID</span>
                <MonoText size="sm">{selectedExchange.orderId}</MonoText>
              </div>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Route</span>
                <span>{selectedExchange.route}</span>
              </div>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Status</span>
                <span className={styles.statusCell}>
                  <StatusDot variant={statusToVariant(selectedExchange.status)} />
                  <span>{statusLabel(selectedExchange.status)}</span>
                </span>
              </div>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Duration</span>
                <MonoText size="sm">{formatDuration(selectedExchange.durationMs)}</MonoText>
              </div>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Customer</span>
                <MonoText size="sm">{selectedExchange.customer}</MonoText>
              </div>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Agent</span>
                <MonoText size="sm">{selectedExchange.agent}</MonoText>
              </div>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Correlation ID</span>
                <MonoText size="xs">{selectedExchange.correlationId}</MonoText>
              </div>
              <div className={styles.overviewRow}>
                <span className={styles.overviewLabel}>Timestamp</span>
                <MonoText size="xs">{selectedExchange.timestamp.toISOString()}</MonoText>
              </div>
              {selectedExchange.errorMessage && (
                <div className={styles.errorBlock}>
                  <div className={styles.errorClass}>{selectedExchange.errorClass}</div>
                  <div className={styles.errorMessage}>{selectedExchange.errorMessage}</div>
                </div>
              )}
            </div>
          ),
        },
        {
          label: 'Processors',
          value: 'processors',
          content: (
            <div className={styles.processorsTab}>
              <ProcessorTimeline
                processors={selectedExchange.processors}
                totalMs={selectedExchange.durationMs}
              />
            </div>
          ),
        },
        {
          label: 'Exchange',
          value: 'exchange',
          content: (
            <div className={styles.exchangeTab}>
              <div className={styles.emptyTabMsg}>Exchange snapshot not available in mock mode.</div>
            </div>
          ),
        },
        {
          label: 'Error',
          value: 'error',
          content: (
            <div className={styles.errorTab}>
              {selectedExchange.errorMessage ? (
                <>
                  <div className={styles.errorClass}>{selectedExchange.errorClass}</div>
                  <pre className={styles.errorPre}>{selectedExchange.errorMessage}</pre>
                </>
              ) : (
                <div className={styles.emptyTabMsg}>No error for this exchange.</div>
              )}
            </div>
          ),
        },
      ]
    : []

  return (
    <AppShell
      sidebar={
        <Sidebar apps={SIDEBAR_APPS} />
      }
      detail={
        selectedExchange ? (
          <DetailPanel
            open={panelOpen}
            onClose={() => setPanelOpen(false)}
            title={`${selectedExchange.orderId} — ${selectedExchange.route}`}
            tabs={detailTabs}
          />
        ) : undefined
      }
    >
      {/* Top bar */}
      <TopBar
        breadcrumb={appId
          ? [{ label: 'Applications', href: '/apps' }, { label: appId }]
          : [{ label: 'Applications' }]
        }
        environment="PRODUCTION"
        user={{ name: 'hendrik' }}
      />

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

        {/* Health strip */}
        <div className={styles.healthStrip}>
          {kpiMetrics.map((kpi, i) => (
            <StatCard
              key={i}
              label={kpi.label}
              value={kpi.value}
              detail={kpi.detail}
              trend={kpi.trend}
              trendValue={kpi.trendValue}
              accent={kpi.accent}
              sparkline={kpi.sparkline}
            />
          ))}
        </div>

        {/* 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}>
                {filteredExchanges.length.toLocaleString()} of {scopedExchanges.length.toLocaleString()} exchanges
              </span>
              <Badge label="LIVE" color="success" />
            </div>
          </div>

          <DataTable
            columns={COLUMNS}
            data={filteredExchanges}
            onRowClick={handleRowClick}
            selectedId={selectedId}
            sortable
            rowAccent={handleRowAccent}
            expandedContent={(row) =>
              row.errorMessage ? (
                <div className={styles.inlineError}>
                  <span className={styles.inlineErrorIcon}>⚠</span>
                  <div>
                    <div className={styles.inlineErrorText}>{row.errorMessage}</div>
                    <div className={styles.inlineErrorHint}>Click to view full stack trace</div>
                  </div>
                </div>
              ) : null
            }
          />
        </div>
      </div>

      {/* Shortcuts bar */}
      <ShortcutsBar shortcuts={SHORTCUTS} />
    </AppShell>
  )
}
