import { useMemo } from 'react';
import { useParams, useNavigate } from 'react-router';
import {
  KpiStrip,
  DataTable,
  ThemedChart,
  Area,
  Line,
  Bar,
  ReferenceLine,
  CHART_COLORS,
  Card,
  Sparkline,
  MonoText,
  Badge,
} from '@cameleer/design-system';
import type { KpiItem, Column } from '@cameleer/design-system';
import { useGlobalFilters } from '@cameleer/design-system';
import { useRouteMetrics } from '../../api/queries/catalog';
import { useExecutionStats, useStatsTimeseries } from '../../api/queries/executions';
import { useEnvironmentStore } from '../../api/environment-store';
import type { RouteMetrics } from '../../api/types';
import styles from './RoutesMetrics.module.css';
import tableStyles from '../../styles/table-section.module.css';
import refreshStyles from '../../styles/refresh-indicator.module.css';
import rateStyles from '../../styles/rate-colors.module.css';

interface RouteRow {
  id: string;
  routeId: string;
  appId: string;
  exchangeCount: number;
  successRate: number;
  avgDurationMs: number;
  p99DurationMs: number;
  errorRate: number;
  throughputPerSec: number;
  sparkline: number[];
}

// ── Route table columns ──────────────────────────────────────────────────────

const ROUTE_COLUMNS: Column<RouteRow>[] = [
  {
    key: 'routeId',
    header: 'Route',
    sortable: true,
    render: (_, row) => (
      <span className={styles.routeNameCell}>{row.routeId}</span>
    ),
  },
  {
    key: 'appId',
    header: 'Application',
    sortable: true,
    render: (_, row) => (
      <span className={styles.appCell}>{row.appId}</span>
    ),
  },
  {
    key: 'exchangeCount',
    header: 'Exchanges',
    sortable: true,
    render: (_, row) => (
      <MonoText size="sm">{row.exchangeCount.toLocaleString()}</MonoText>
    ),
  },
  {
    key: 'successRate',
    header: 'Success %',
    sortable: true,
    render: (_, row) => {
      const pct = row.successRate * 100;
      const cls = pct >= 99 ? rateStyles.rateGood : pct >= 97 ? rateStyles.rateWarn : rateStyles.rateBad;
      return <MonoText size="sm" className={cls}>{pct.toFixed(1)}%</MonoText>;
    },
  },
  {
    key: 'avgDurationMs',
    header: 'Avg Duration',
    sortable: true,
    render: (_, row) => (
      <MonoText size="sm">{Math.round(row.avgDurationMs)}ms</MonoText>
    ),
  },
  {
    key: 'p99DurationMs',
    header: 'p99 Duration',
    sortable: true,
    render: (_, row) => {
      const cls = row.p99DurationMs > 300 ? rateStyles.rateBad : row.p99DurationMs > 200 ? rateStyles.rateWarn : rateStyles.rateGood;
      return <MonoText size="sm" className={cls}>{Math.round(row.p99DurationMs)}ms</MonoText>;
    },
  },
  {
    key: 'errorRate',
    header: 'Error Rate',
    sortable: true,
    render: (_, row) => {
      const pct = row.errorRate * 100;
      const cls = pct > 5 ? rateStyles.rateBad : pct > 1 ? rateStyles.rateWarn : rateStyles.rateGood;
      return <MonoText size="sm" className={cls}>{pct.toFixed(1)}%</MonoText>;
    },
  },
  {
    key: 'sparkline',
    header: 'Trend',
    render: (_, row) => (
      <Sparkline data={row.sparkline} width={80} height={24} />
    ),
  },
];

// ── Build KPI items from backend stats ───────────────────────────────────────

function buildKpiItems(
  stats: {
    totalCount: number;
    failedCount: number;
    avgDurationMs: number;
    p99LatencyMs: number;
    activeCount: number;
    prevTotalCount: number;
    prevFailedCount: number;
    prevP99LatencyMs: number;
  } | undefined,
  routeCount: number,
  throughputSparkline: number[],
  errorSparkline: number[],
): KpiItem[] {
  const totalCount = stats?.totalCount ?? 0;
  const failedCount = stats?.failedCount ?? 0;
  const prevTotalCount = stats?.prevTotalCount ?? 0;
  const p99Ms = stats?.p99LatencyMs ?? 0;
  const prevP99Ms = stats?.prevP99LatencyMs ?? 0;
  const avgMs = stats?.avgDurationMs ?? 0;
  const activeCount = stats?.activeCount ?? 0;

  const errorRate = totalCount > 0 ? (failedCount / totalCount) * 100 : 0;

  const throughputPctChange = prevTotalCount > 0
    ? Math.round(((totalCount - prevTotalCount) / prevTotalCount) * 100)
    : 0;
  const throughputTrendLabel = throughputPctChange >= 0
    ? `\u25B2 +${throughputPctChange}%`
    : `\u25BC ${throughputPctChange}%`;

  const p50 = Math.round(avgMs * 0.5);
  const p95 = Math.round(avgMs * 1.4);
  const slaStatus = p99Ms > 300 ? 'BREACH' : 'OK';

  const prevErrorRate = prevTotalCount > 0
    ? ((stats?.prevFailedCount ?? 0) / prevTotalCount) * 100
    : 0;
  const errorDelta = (errorRate - prevErrorRate).toFixed(1);

  return [
    {
      label: 'Total Throughput',
      value: totalCount.toLocaleString(),
      trend: {
        label: throughputTrendLabel,
        variant: throughputPctChange >= 0 ? 'success' as const : 'error' as const,
      },
      subtitle: `${activeCount} active exchanges`,
      sparkline: throughputSparkline,
      borderColor: 'var(--amber)',
    },
    {
      label: 'System Error Rate',
      value: `${errorRate.toFixed(2)}%`,
      trend: {
        label: errorRate <= prevErrorRate ? `\u25BC ${errorDelta}%` : `\u25B2 +${errorDelta}%`,
        variant: errorRate < 1 ? 'success' as const : 'error' as const,
      },
      subtitle: `${failedCount} errors / ${totalCount.toLocaleString()} total`,
      sparkline: errorSparkline,
      borderColor: errorRate < 1 ? 'var(--success)' : 'var(--error)',
    },
    {
      label: 'Latency Percentiles',
      value: `${p99Ms}ms`,
      trend: {
        label: p99Ms > prevP99Ms ? `\u25B2 +${p99Ms - prevP99Ms}ms` : `\u25BC ${prevP99Ms - p99Ms}ms`,
        variant: p99Ms > 300 ? 'error' as const : 'warning' as const,
      },
      subtitle: `P50 ${p50}ms \u00B7 P95 ${p95}ms \u00B7 SLA <300ms P99: ${slaStatus}`,
      borderColor: p99Ms > 300 ? 'var(--warning)' : 'var(--success)',
    },
    {
      label: 'Active Routes',
      value: `${routeCount}`,
      trend: { label: '\u2194 stable', variant: 'muted' as const },
      subtitle: `${routeCount} routes reporting`,
      borderColor: 'var(--running)',
    },
    {
      label: 'In-Flight Exchanges',
      value: String(activeCount),
      trend: { label: '\u2194', variant: 'muted' as const },
      subtitle: `${activeCount} active`,
      sparkline: throughputSparkline,
      borderColor: 'var(--amber)',
    },
  ];
}

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

export default function RoutesMetrics() {
  const { appId } = useParams();
  const navigate = useNavigate();
  const selectedEnv = useEnvironmentStore((s) => s.environment);
  const { timeRange } = useGlobalFilters();
  const timeFrom = timeRange.start.toISOString();
  const timeTo = timeRange.end.toISOString();

  const { data: metrics } = useRouteMetrics(timeFrom, timeTo, appId, selectedEnv);
  const { data: stats } = useExecutionStats(timeFrom, timeTo, undefined, appId, selectedEnv);
  const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, undefined, appId, selectedEnv);

  // Map backend RouteMetrics[] to table rows
  const rows: RouteRow[] = useMemo(() =>
    (metrics || []).map((m: RouteMetrics) => ({
      id: `${m.appId}/${m.routeId}`,
      routeId: m.routeId,
      appId: m.appId,
      exchangeCount: m.exchangeCount,
      successRate: m.successRate,
      avgDurationMs: m.avgDurationMs,
      p99DurationMs: m.p99DurationMs,
      errorRate: m.errorRate,
      throughputPerSec: m.throughputPerSec,
      sparkline: m.sparkline ?? [],
    })),
    [metrics],
  );

  // Sparkline data from timeseries buckets
  const throughputSparkline = useMemo(() =>
    (timeseries?.buckets || []).map((b) => b.totalCount),
    [timeseries],
  );
  const errorSparkline = useMemo(() =>
    (timeseries?.buckets || []).map((b) => b.failedCount),
    [timeseries],
  );

  // Flat chart data from timeseries buckets
  const chartData = useMemo(() =>
    (timeseries?.buckets || []).map((b, i) => ({
      idx: i,
      throughput: b.totalCount,
      latency: b.avgDurationMs,
      errors: b.failedCount,
      volume: b.totalCount,
    })),
    [timeseries],
  );

  const kpiItems = useMemo(() =>
    buildKpiItems(stats, rows.length, throughputSparkline, errorSparkline),
    [stats, rows.length, throughputSparkline, errorSparkline],
  );

  return (
    <div className={styles.content}>
      <div className={refreshStyles.refreshIndicator}>
        <span className={refreshStyles.refreshDot} />
        <span className={refreshStyles.refreshText}>Auto-refresh: 30s</span>
      </div>

      {/* KPI header cards */}
      <KpiStrip items={kpiItems} />

      {/* Per-route performance table */}
      <div className={tableStyles.tableSection}>
        <div className={tableStyles.tableHeader}>
          <span className={tableStyles.tableTitle}>Per-Route Performance</span>
          <div className={tableStyles.tableRight}>
            <span className={tableStyles.tableMeta}>{rows.length} routes</span>
            <Badge label="AUTO" color="success" />
          </div>
        </div>
        <DataTable
          columns={ROUTE_COLUMNS}
          data={rows}
          sortable
          onRowClick={(row) => {
            const targetAppId = appId ?? row.appId;
            navigate(`/routes/${targetAppId}/${row.routeId}`);
          }}
        />
      </div>

      {/* 2x2 chart grid */}
      {chartData.length > 0 && (
        <div className={styles.chartGrid}>
          <Card title="Throughput (msg/s)">
            <ThemedChart data={chartData} height={200} xDataKey="idx" yLabel="msg/s">
              <Area dataKey="throughput" name="Throughput" stroke={CHART_COLORS[0]}
                fill={CHART_COLORS[0]} fillOpacity={0.1} strokeWidth={2} dot={false} />
            </ThemedChart>
          </Card>

          <Card title="Latency (ms)">
            <ThemedChart data={chartData} height={200} xDataKey="idx" yLabel="ms">
              <Line dataKey="latency" name="Latency" stroke={CHART_COLORS[0]} strokeWidth={2} dot={false} />
              <ReferenceLine y={300} stroke="var(--error)" strokeDasharray="5 3"
                label={{ value: 'SLA 300ms', position: 'right', fill: 'var(--error)', fontSize: 9 }} />
            </ThemedChart>
          </Card>

          <Card title="Errors by Bucket">
            <ThemedChart data={chartData} height={200} xDataKey="idx" yLabel="errors">
              <Bar dataKey="errors" name="Errors" fill={CHART_COLORS[1]} />
            </ThemedChart>
          </Card>

          <Card title="Message Volume (msg/min)">
            <ThemedChart data={chartData} height={200} xDataKey="idx" yLabel="msg/min">
              <Area dataKey="volume" name="Volume" stroke={CHART_COLORS[0]}
                fill={CHART_COLORS[0]} fillOpacity={0.1} strokeWidth={2} dot={false} />
            </ThemedChart>
          </Card>
        </div>
      )}
    </div>
  );
}
