import { useMemo } from 'react';
import { useNavigate } from 'react-router';
import { GitBranch, Server, RotateCcw } from 'lucide-react';
import { StatusDot, MonoText, Badge } from '@cameleer/design-system';
import { useCorrelationChain } from '../../api/queries/correlation';
import { useAgents } from '../../api/queries/agents';
import { useAuthStore } from '../../auth/auth-store';
import type { ExecutionDetail } from '../../components/ExecutionDiagram/types';
import { attributeBadgeColor } from '../../utils/attribute-color';
import { RouteControlBar } from './RouteControlBar';
import styles from './ExchangeHeader.module.css';

interface ExchangeHeaderProps {
  detail: ExecutionDetail;
  onCorrelatedSelect?: (executionId: string, applicationName: string, routeId: string) => void;
  onClearSelection?: () => void;
}

type StatusVariant = 'success' | 'error' | 'running' | 'warning';

function statusVariant(s: string): StatusVariant {
  switch (s) {
    case 'COMPLETED': return 'success';
    case 'FAILED': return 'error';
    case 'RUNNING': return 'running';
    default: return 'warning';
  }
}

function statusLabel(s: string): string {
  switch (s) {
    case 'COMPLETED': return 'OK';
    case 'FAILED': return 'ERR';
    case 'RUNNING': return 'RUN';
    default: return s;
  }
}

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`;
}

export function ExchangeHeader({ detail, onCorrelatedSelect, onClearSelection }: ExchangeHeaderProps) {
  const navigate = useNavigate();
  const { data: chainResult } = useCorrelationChain(detail.correlationId ?? null);
  const chain = chainResult?.data;
  const showChain = chain && chain.length > 1;
  const attrs = Object.entries(detail.attributes ?? {});

  // Look up agent state for icon coloring + route control capability
  const { data: agents } = useAgents(undefined, detail.applicationName);
  const { agentState, hasRouteControl, hasReplay } = useMemo(() => {
    if (!agents) return { agentState: undefined, hasRouteControl: false, hasReplay: false };
    const agentList = agents as any[];
    const agent = detail.agentId ? agentList.find((a: any) => a.id === detail.agentId) : undefined;
    return {
      agentState: agent?.state?.toLowerCase() as 'live' | 'stale' | 'dead' | undefined,
      hasRouteControl: agentList.some((a: any) => a.capabilities?.routeControl === true),
      hasReplay: agentList.some((a: any) => a.capabilities?.replay === true),
    };
  }, [agents, detail.agentId]);

  const roles = useAuthStore((s) => s.roles);
  const canControl = roles.some(r => r === 'OPERATOR' || r === 'ADMIN');

  return (
    <div className={styles.header}>
      {/* Exchange info — always shown */}
      <div className={styles.info}>
        <StatusDot variant={statusVariant(detail.status)} />
        <Badge label={statusLabel(detail.status)} color={statusVariant(detail.status)} />
        {attrs.length > 0 && (
          <>
            <span className={styles.separator} />
            {attrs.map(([k, v]) => (
              <Badge key={k} label={`${k}: ${v}`} color={attributeBadgeColor(String(v))} />
            ))}
          </>
        )}
        <span className={styles.separator} />
        <button className={styles.linkBtn} onClick={() => { onClearSelection?.(); navigate(`/exchanges/${detail.applicationName}`); }} title="Show all exchanges for this application">
          <span className={styles.app}>{detail.applicationName}</span>
        </button>
        <button className={styles.linkBtn} onClick={() => { onClearSelection?.(); navigate(`/exchanges/${detail.applicationName}/${detail.routeId}`); }} title="Show all exchanges for this route">
          <span className={styles.route}>{detail.routeId}</span>
          <GitBranch size={12} className={styles.icon} />
        </button>
        {detail.agentId && (
          <>
            <span className={styles.separator} />
            <button className={styles.linkBtn} onClick={() => navigate(`/runtime/${detail.applicationName}`)} title="All agents for this application">
              <span className={styles.app}>{detail.applicationName}</span>
            </button>
            <button className={styles.linkBtn} onClick={() => navigate(`/runtime/${detail.applicationName}/${detail.agentId}`)} title="Agent details">
              <MonoText size="xs">{detail.agentId}</MonoText>
              <Server size={12} className={agentState === 'live' ? styles.iconLive : agentState === 'stale' ? styles.iconStale : agentState === 'dead' ? styles.iconDead : styles.icon} />
            </button>
          </>
        )}
        <span className={styles.duration}>{formatDuration(detail.durationMs)}</span>
      </div>

      {/* Route control / replay — only if agent supports it AND user has operator+ role */}
      {canControl && (hasRouteControl || hasReplay) && (
        <RouteControlBar
          application={detail.applicationName}
          routeId={detail.routeId}
          hasRouteControl={hasRouteControl}
          hasReplay={hasReplay}
          agentId={detail.agentId}
          exchangeId={detail.exchangeId}
          inputHeaders={detail.inputHeaders}
          inputBody={detail.inputBody}
        />
      )}

      {/* Correlation chain */}
      <div className={styles.chain}>
        <span className={styles.chainLabel}>Correlated</span>
        {showChain ? chain.map((ce: any, i: number) => {
            const isCurrent = ce.executionId === detail.executionId;
            const variant = statusVariant(ce.status);
            const isReplay = !!ce.isReplay;
            const statusCls =
              variant === 'success' ? styles.chainNodeSuccess
              : variant === 'error' ? styles.chainNodeError
              : variant === 'running' ? styles.chainNodeRunning
              : styles.chainNodeWarning;
            return (
              <span key={ce.executionId} className={styles.chainEntry}>
                {i > 0 && <span className={styles.chainArrow}>&rarr;</span>}
                <button
                  className={`${styles.chainNode} ${statusCls} ${isCurrent ? styles.chainNodeCurrent : ''}`}
                  onClick={() => {
                    if (!isCurrent && onCorrelatedSelect) {
                      onCorrelatedSelect(ce.executionId, ce.applicationName ?? detail.applicationName, ce.routeId);
                    }
                  }}
                  title={`${ce.executionId}\n${ce.routeId} \u2014 ${formatDuration(ce.durationMs)}${isReplay ? '\n(replay)' : ''}`}
                >
                  <StatusDot variant={variant} />
                  {isReplay && <RotateCcw size={9} className={styles.replayIcon} />}
                  <span className={styles.chainRoute}>{ce.routeId}</span>
                  <span className={styles.chainDuration}>{formatDuration(ce.durationMs)}</span>
                </button>
              </span>
            );
          }) : (
            <span className={styles.chainNone}>no correlated exchanges found</span>
          )}
        {showChain && (() => {
          const starts = chain.map((ce: any) => new Date(ce.startTime).getTime()).filter((t: number) => !isNaN(t));
          const ends = chain.map((ce: any) => new Date(ce.endTime ?? ce.startTime).getTime() + (ce.durationMs ?? 0)).filter((t: number) => !isNaN(t));
          const totalMs = starts.length > 0 && ends.length > 0 ? Math.max(...ends) - Math.min(...starts) : 0;
          return totalMs > 0 ? <span className={styles.chainTotal}>{formatDuration(totalMs)}</span> : null;
        })()}
      </div>
    </div>
  );
}
