import { useMemo } from 'react';
import { useParams } from 'react-router';
import {
  StatCard, StatusDot, Badge, Card,
  LineChart, AreaChart, BarChart, EventFeed, Breadcrumb, Spinner, EmptyState,
} from '@cameleer/design-system';
import styles from './AgentInstance.module.css';
import { useAgents, useAgentEvents } from '../../api/queries/agents';
import { useStatsTimeseries } from '../../api/queries/executions';
import { useAgentMetrics } from '../../api/queries/agent-metrics';
import { useGlobalFilters } from '@cameleer/design-system';

export default function AgentInstance() {
  const { appId, instanceId } = useParams();
  const { timeRange } = useGlobalFilters();
  const timeFrom = timeRange.start.toISOString();
  const timeTo = timeRange.end.toISOString();

  const { data: agents, isLoading } = useAgents(undefined, appId);
  const { data: events } = useAgentEvents(appId, instanceId);
  const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, undefined, appId);

  const agent = useMemo(() =>
    (agents || []).find((a: any) => a.id === instanceId) as any,
    [agents, instanceId],
  );

  // Stat card metrics (latest 1 bucket)
  const { data: latestMetrics } = useAgentMetrics(
    agent?.id || null,
    ['jvm.cpu.process', 'jvm.memory.heap.used', 'jvm.memory.heap.max'],
    1,
  );
  const cpuPct = latestMetrics?.metrics?.['jvm.cpu.process']?.[0]?.value;
  const heapUsed = latestMetrics?.metrics?.['jvm.memory.heap.used']?.[0]?.value;
  const heapMax = latestMetrics?.metrics?.['jvm.memory.heap.max']?.[0]?.value;
  const memPct = heapMax ? (heapUsed! / heapMax) * 100 : undefined;

  // Chart metrics (60 buckets)
  const { data: jvmMetrics } = useAgentMetrics(
    agent?.id || null,
    ['jvm.cpu.process', 'jvm.memory.heap.used', 'jvm.memory.heap.max', 'jvm.threads.count', 'jvm.gc.time'],
    60,
  );

  const chartData = useMemo(() =>
    (timeseries?.buckets || []).map((b: any) => ({
      time: new Date(b.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
      throughput: b.totalCount,
      latency: b.avgDurationMs,
      errors: b.failedCount,
    })),
    [timeseries],
  );

  const feedEvents = useMemo(() =>
    (events || []).filter((e: any) => !instanceId || e.agentId === instanceId).map((e: any) => ({
      id: String(e.id),
      severity: e.eventType === 'WENT_DEAD' ? 'error' as const
        : e.eventType === 'WENT_STALE' ? 'warning' as const
        : e.eventType === 'RECOVERED' ? 'success' as const
        : 'running' as const,
      message: `${e.eventType}${e.detail ? ' — ' + e.detail : ''}`,
      timestamp: new Date(e.timestamp),
    })),
    [events, instanceId],
  );

  // JVM chart series helpers
  const cpuSeries = useMemo(() => {
    const pts = jvmMetrics?.metrics?.['jvm.cpu.process'];
    if (!pts?.length) return null;
    return [{ label: 'CPU %', data: pts.map((p: any, i: number) => ({ x: i, y: p.value * 100 })) }];
  }, [jvmMetrics]);

  const heapSeries = useMemo(() => {
    const pts = jvmMetrics?.metrics?.['jvm.memory.heap.used'];
    if (!pts?.length) return null;
    return [{ label: 'Heap MB', data: pts.map((p: any, i: number) => ({ x: i, y: p.value / (1024 * 1024) })) }];
  }, [jvmMetrics]);

  const threadSeries = useMemo(() => {
    const pts = jvmMetrics?.metrics?.['jvm.threads.count'];
    if (!pts?.length) return null;
    return [{ label: 'Threads', data: pts.map((p: any, i: number) => ({ x: i, y: p.value })) }];
  }, [jvmMetrics]);

  const gcSeries = useMemo(() => {
    const pts = jvmMetrics?.metrics?.['jvm.gc.time'];
    if (!pts?.length) return null;
    return [{ label: 'GC ms', data: pts.map((p: any, i: number) => ({ x: String(i), y: p.value })) }];
  }, [jvmMetrics]);

  const throughputSeries = useMemo(() =>
    chartData.length ? [{ label: 'Throughput', data: chartData.map((d: any, i: number) => ({ x: i, y: d.throughput })) }] : null,
    [chartData],
  );

  const errorSeries = useMemo(() =>
    chartData.length ? [{ label: 'Errors', data: chartData.map((d: any, i: number) => ({ x: i, y: d.errors })) }] : null,
    [chartData],
  );

  if (isLoading) return <Spinner size="lg" />;

  return (
    <div>
      <Breadcrumb items={[
        { label: 'Agents', href: '/agents' },
        { label: appId || '', href: `/agents/${appId}` },
        { label: agent?.name || instanceId || '' },
      ]} />

      {agent && (
        <>
          <div className={styles.agentHeader}>
            <StatusDot variant={agent.status === 'LIVE' ? 'live' : agent.status === 'STALE' ? 'stale' : 'dead'} />
            <h2>{agent.name}</h2>
            <Badge label={agent.status} color={agent.status === 'LIVE' ? 'success' : agent.status === 'STALE' ? 'warning' : 'error'} />
            {agent.version && <Badge label={agent.version} variant="outlined" />}
          </div>

          <div className={styles.statStrip}>
            <StatCard label="CPU" value={cpuPct != null ? `${(cpuPct * 100).toFixed(0)}%` : '—'} />
            <StatCard
              label="Memory"
              value={memPct != null ? `${memPct.toFixed(0)}%` : '—'}
              detail={heapUsed != null && heapMax != null ? `${(heapUsed / (1024 * 1024)).toFixed(0)} MB / ${(heapMax / (1024 * 1024)).toFixed(0)} MB` : undefined}
            />
            <StatCard label="Throughput" value={agent?.tps != null ? `${agent.tps.toFixed(1)}/s` : '—'} />
            <StatCard label="Errors" value={agent?.errorRate != null ? `${(agent.errorRate * 100).toFixed(1)}%` : '—'} accent={agent?.errorRate > 0 ? 'error' : undefined} />
            <StatCard
              label="Uptime"
              value={formatUptime(agent?.uptimeSeconds)}
              detail={agent?.registeredAt ? `since ${new Date(agent.registeredAt).toLocaleDateString()}` : undefined}
            />
          </div>

          <div className={styles.scopeTrail}>
            <a href="/agents" className={styles.scopeLink}>All Agents</a>
            <span className={styles.scopeSep}>&#9656;</span>
            <a href={`/agents/${appId}`} className={styles.scopeLink}>{appId}</a>
            <span className={styles.scopeSep}>&#9656;</span>
            <span className={styles.scopeCurrent}>{agent.name}</span>
            <Badge
              label={agent.status.toUpperCase()}
              color={agent.status === 'LIVE' ? 'success' : agent.status === 'STALE' ? 'warning' : 'error'}
            />
            {agent.version && <Badge label={agent.version} variant="outlined" />}
            <Badge
              label={`${agent.activeRoutes ?? (agent.routeIds?.length ?? 0)}/${agent.totalRoutes ?? (agent.routeIds?.length ?? 0)} routes`}
              color={(agent.activeRoutes ?? 0) < (agent.totalRoutes ?? 0) ? 'warning' : 'success'}
            />
          </div>

          <Card className={styles.infoCard}>
            <div className={styles.paneTitle}>Process Information</div>
            <div className={styles.infoGrid}>
              {agent?.capabilities?.jvmVersion && (
                <div>
                  <span className={styles.infoLabel}>JVM</span>
                  <span>{agent.capabilities.jvmVersion}</span>
                </div>
              )}
              {agent?.capabilities?.camelVersion && (
                <div>
                  <span className={styles.infoLabel}>Camel</span>
                  <span>{agent.capabilities.camelVersion}</span>
                </div>
              )}
              {agent?.capabilities?.springBootVersion && (
                <div>
                  <span className={styles.infoLabel}>Spring Boot</span>
                  <span>{agent.capabilities.springBootVersion}</span>
                </div>
              )}
              <div>
                <span className={styles.infoLabel}>Started</span>
                <span>{agent?.registeredAt ? new Date(agent.registeredAt).toLocaleString() : '—'}</span>
              </div>
              <div>
                <span className={styles.infoLabel}>Capabilities</span>
                <span className={styles.capTags}>
                  {Object.entries(agent?.capabilities || {})
                    .filter(([, v]) => typeof v === 'boolean' && v)
                    .map(([k]) => (
                      <Badge key={k} label={k} variant="outlined" />
                    ))}
                </span>
              </div>
            </div>
          </Card>

          <div className={styles.sectionTitle}>Routes</div>
          <div className={styles.routeBadges}>
            {(agent.routeIds || []).map((r: string) => (
              <Badge key={r} label={r} color="auto" />
            ))}
          </div>
        </>
      )}

      <div className={styles.sectionTitle}>Performance</div>
      <div className={styles.chartsGrid}>
        <div className={styles.chartCard}>
          <div className={styles.chartHeader}><div className={styles.chartTitle}>CPU Usage</div></div>
          {cpuSeries
            ? <AreaChart series={cpuSeries} yLabel="%" height={200} />
            : <EmptyState title="No data" description="No CPU metrics available" />}
        </div>
        <div className={styles.chartCard}>
          <div className={styles.chartHeader}><div className={styles.chartTitle}>Memory Heap</div></div>
          {heapSeries
            ? <AreaChart series={heapSeries} yLabel="MB" height={200} />
            : <EmptyState title="No data" description="No heap metrics available" />}
        </div>
        <div className={styles.chartCard}>
          <div className={styles.chartHeader}><div className={styles.chartTitle}>Throughput</div></div>
          {throughputSeries
            ? <AreaChart series={throughputSeries} height={200} />
            : <EmptyState title="No data" description="No throughput data in range" />}
        </div>
        <div className={styles.chartCard}>
          <div className={styles.chartHeader}><div className={styles.chartTitle}>Error Rate</div></div>
          {errorSeries
            ? <LineChart series={errorSeries} height={200} />
            : <EmptyState title="No data" description="No error data in range" />}
        </div>
        <div className={styles.chartCard}>
          <div className={styles.chartHeader}><div className={styles.chartTitle}>Thread Count</div></div>
          {threadSeries
            ? <LineChart series={threadSeries} height={200} />
            : <EmptyState title="No data" description="No thread metrics available" />}
        </div>
        <div className={styles.chartCard}>
          <div className={styles.chartHeader}><div className={styles.chartTitle}>GC Pauses</div></div>
          {gcSeries
            ? <BarChart series={gcSeries} yLabel="ms" height={200} />
            : <EmptyState title="No data" description="No GC metrics available" />}
        </div>
      </div>

      {feedEvents.length > 0 && (
        <div className={styles.eventCard}>
          <div className={styles.eventCardHeader}>Events</div>
          <EventFeed events={feedEvents} maxItems={50} />
        </div>
      )}

      <EmptyState title="Application Logs" description="Application log streaming is not yet available" />
    </div>
  );
}

function formatUptime(seconds?: number): string {
  if (!seconds) return '—';
  const days = Math.floor(seconds / 86400);
  const hours = Math.floor((seconds % 86400) / 3600);
  const mins = Math.floor((seconds % 3600) / 60);
  if (days > 0) return `${days}d ${hours}h`;
  if (hours > 0) return `${hours}h ${mins}m`;
  return `${mins}m`;
}
