import { useState, useCallback } from 'react';
import { Play, Square, Pause, PlayCircle, RotateCcw, Loader2 } from 'lucide-react';
import { useToast, ConfirmDialog } from '@cameleer/design-system';
import { useSendRouteCommand, useReplayExchange } from '../../api/queries/commands';
import type { CommandGroupResponse } from '../../api/queries/commands';
import { useEnvironmentStore } from '../../api/environment-store';
import { describeApiError } from '../../api/errors';
import styles from './RouteControlBar.module.css';

interface RouteControlBarProps {
  application: string;
  routeId: string;
  routeState?: 'started' | 'stopped' | 'suspended';
  hasRouteControl: boolean;
  hasReplay: boolean;
  agentId?: string;
  exchangeId?: string;
  inputHeaders?: string;
  inputBody?: string;
}

type RouteAction = 'start' | 'stop' | 'suspend' | 'resume';

const ROUTE_ACTIONS: { action: RouteAction; label: string; icon: typeof Play; colorClass: string }[] = [
  { action: 'start',   label: 'Start',   icon: Play,       colorClass: styles.success },
  { action: 'stop',    label: 'Stop',    icon: Square,     colorClass: styles.danger },
  { action: 'suspend', label: 'Suspend', icon: Pause,      colorClass: styles.warning },
  { action: 'resume',  label: 'Resume',  icon: PlayCircle, colorClass: styles.success },
];

const ACTION_DISABLED: Record<string, Set<RouteAction>> = {
  started:   new Set(['start', 'resume']),
  stopped:   new Set(['stop', 'suspend', 'resume']),
  suspended: new Set(['start', 'suspend']),
};

export function RouteControlBar({ application, routeId, routeState, hasRouteControl, hasReplay, agentId, exchangeId, inputHeaders, inputBody }: RouteControlBarProps) {
  const { toast } = useToast();
  const selectedEnv = useEnvironmentStore((s) => s.environment);
  const sendRouteCommand = useSendRouteCommand();
  const replayExchange = useReplayExchange();
  const [sendingAction, setSendingAction] = useState<string | null>(null);

  const [pendingConfirm, setPendingConfirm] = useState<RouteAction | null>(null);

  const busy = sendingAction !== null;
  const disabledActions = ACTION_DISABLED[routeState ?? 'started'] ?? new Set();

  const handleRouteClick = useCallback((action: RouteAction) => {
    if (action === 'stop' || action === 'suspend') {
      setPendingConfirm(action);
    } else {
      handleRouteAction(action);
    }
  }, []);

  function handleRouteAction(action: RouteAction) {
    setSendingAction(action);
    sendRouteCommand.mutate(
      { application, action, routeId, environment: selectedEnv },
      {
        onSuccess: (result: CommandGroupResponse) => {
          if (result.success) {
            toast({ title: `Route ${action} sent`, description: `${routeId} — ${result.total}/${result.total} agents responded`, variant: 'success' });
          } else {
            const failedAgents = [...result.responses.filter(r => r.status !== 'SUCCESS').map(r => r.agentId), ...result.timedOut];
            toast({ title: `Route ${action} — partial failure`, description: `${result.responded}/${result.total} responded. Failed: ${failedAgents.join(', ')}`, variant: 'warning', duration: 86_400_000 });
          }
          setSendingAction(null);
        },
        onError: (err) => {
          toast({ title: `Route ${action} failed`, description: describeApiError(err), variant: 'error', duration: 86_400_000 });
          setSendingAction(null);
        },
      },
    );
  }

  function handleReplay() {
    if (!agentId) return;
    let headers: Record<string, string> = {};
    try { headers = inputHeaders ? JSON.parse(inputHeaders) : {}; } catch { /* empty */ }
    setSendingAction('replay');
    replayExchange.mutate(
      { agentId, routeId, headers, body: inputBody ?? '', originalExchangeId: exchangeId },
      {
        onSuccess: (result) => {
          if (result.status === 'SUCCESS') {
            toast({ title: 'Replay completed', description: result.message ?? `${routeId} on ${agentId}`, variant: 'success' });
          } else {
            toast({ title: 'Replay failed', description: result.message ?? 'Agent reported failure', variant: 'error', duration: 86_400_000 });
          }
          setSendingAction(null);
        },
        onError: (err) => {
          toast({ title: 'Replay failed', description: describeApiError(err), variant: 'error', duration: 86_400_000 });
          setSendingAction(null);
        },
      },
    );
  }

  return (
    <div className={styles.bar}>
      <span className={styles.label}>Route</span>
      {hasRouteControl && (
        <div className={`${styles.group} ${busy ? styles.sending : ''}`}>
          {ROUTE_ACTIONS.map(({ action, label, icon: Icon, colorClass }) => (
            <button
              key={action}
              className={`${styles.segment} ${colorClass}`}
              disabled={busy || disabledActions.has(action)}
              onClick={() => handleRouteClick(action)}
              title={`${label} route ${routeId}`}
            >
              {sendingAction === action
                ? <Loader2 size={12} className={styles.spinner} />
                : <Icon size={12} />}
              {label}
            </button>
          ))}
        </div>
      )}
      {hasRouteControl && hasReplay && <span className={styles.divider} />}
      {hasReplay && (
        <div className={`${styles.group} ${busy ? styles.sending : ''}`}>
          <button
            className={`${styles.segment} ${styles.success}`}
            disabled={busy || !agentId}
            onClick={handleReplay}
            title={`Replay exchange on ${agentId ?? 'agent'}`}
          >
            {sendingAction === 'replay'
              ? <Loader2 size={12} className={styles.spinner} />
              : <RotateCcw size={12} />}
            Replay
          </button>
        </div>
      )}
      <ConfirmDialog
        open={pendingConfirm !== null}
        onClose={() => setPendingConfirm(null)}
        onConfirm={() => {
          if (pendingConfirm) handleRouteAction(pendingConfirm);
          setPendingConfirm(null);
        }}
        title={`${pendingConfirm === 'stop' ? 'Stop' : 'Suspend'} route?`}
        message={`This will ${pendingConfirm} route "${routeId}" on ${application}. This affects all live agents.`}
        confirmText={pendingConfirm ?? ''}
        confirmLabel={pendingConfirm === 'stop' ? 'Stop Route' : 'Suspend Route'}
        variant={pendingConfirm === 'stop' ? 'danger' : 'warning'}
        loading={busy}
      />
    </div>
  );
}
