import React, { memo } from 'react';
import { Handle, Position, type NodeProps } from '@xyflow/react';
import {
  CheckCircleOutlined,
  ClockCircleOutlined,
  CloseCircleOutlined,
  LoadingOutlined,
} from '@ant-design/icons';

const CATEGORY_COLORS: Record<string, { bg: string; border: string }> = {
  TRIGGER: { bg: '#e6f7ff', border: '#91caff' },
  ACTION: { bg: '#f6ffed', border: '#b7eb8f' },
  CONDITION: { bg: '#fff7e6', border: '#ffd591' },
  LOOP: { bg: '#f9f0ff', border: '#d3adf7' },
  APPROVAL: { bg: '#fff1f0', border: '#ffa39e' },
  SUB_WORKFLOW: { bg: '#f0f5ff', border: '#adc6ff' },
};

// Status-specific background colors (overlay on top of category colors)
const STATUS_COLORS: Record<string, string> = {
  COMPLETED: '#f6ffed', // light green
  RUNNING: '#e6f7ff', // light blue
  FAILED: '#fff1f0', // light red
  PENDING: '#fffbe6', // light yellow
  NOT_EXECUTED: '#fafafa', // gray
};

export interface ExecutionStatusNodeData {
  label: string;
  category: string;
  isSelected: boolean;
  readonly?: boolean;
  executionStatus?:
    | 'PENDING'
    | 'RUNNING'
    | 'COMPLETED'
    | 'FAILED'
    | 'NOT_EXECUTED';
  duration?: string; // e.g., "2.5s"
  error?: string;
  [key: string]: unknown;
}

function formatDuration(
  startedAt: string | null,
  finishedAt: string | null,
): string {
  if (!startedAt) return '';
  const endTime = finishedAt ? new Date(finishedAt).getTime() : Date.now();
  const ms = endTime - new Date(startedAt).getTime();
  if (ms < 1000) return `${ms}ms`;
  const s = ms / 1000;
  if (s < 60) return `${s.toFixed(1)}s`;
  const m = Math.floor(s / 60);
  const rem = s % 60;
  return rem > 0 ? `${m}m ${rem.toFixed(0)}s` : `${m}m`;
}

function getStatusIcon(status?: string) {
  switch (status) {
    case 'COMPLETED':
      return <CheckCircleOutlined style={{ color: '#52c41a', fontSize: 16 }} />;
    case 'RUNNING':
      return <LoadingOutlined style={{ color: '#1677ff', fontSize: 16 }} />;
    case 'FAILED':
      return <CloseCircleOutlined style={{ color: '#ff4d4f', fontSize: 16 }} />;
    case 'NOT_EXECUTED':
      return <ClockCircleOutlined style={{ color: '#bfbfbf', fontSize: 16 }} />;
    case 'PENDING':
    default:
      return <ClockCircleOutlined style={{ color: '#faad14', fontSize: 16 }} />;
  }
}

export const ExecutionStatusNode = memo(({ data }: NodeProps) => {
  const nodeData = data as ExecutionStatusNodeData;
  const colors = CATEGORY_COLORS[nodeData.category] || CATEGORY_COLORS.ACTION;
  const isNotExecuted = nodeData.executionStatus === 'NOT_EXECUTED';

  // If there's execution status, use status color as background; otherwise use category color
  const bgColor = nodeData.executionStatus
    ? STATUS_COLORS[nodeData.executionStatus]
    : colors.bg;

  const borderColor = nodeData.isSelected
    ? '#1677ff'
    : isNotExecuted
      ? '#d9d9d9'
      : colors.border;
  const borderStyle = nodeData.isSelected
    ? '2px solid'
    : isNotExecuted
      ? '1.5px dashed'
      : '1px solid';

  return (
    <div
      style={{
        background: bgColor,
        border: `${borderStyle} ${borderColor}`,
        borderRadius: 8,
        padding: '8px 12px',
        fontSize: 13,
        minWidth: 140,
        textAlign: 'center',
        opacity: isNotExecuted ? 0.6 : 1,
        boxShadow: nodeData.isSelected
          ? '0 0 0 2px rgba(22,119,255,0.2)'
          : !isNotExecuted && nodeData.executionStatus
            ? '0 2px 8px rgba(0,0,0,0.15)'
            : undefined,
        position: 'relative',
        transition: 'all 0.2s ease',
      }}
    >
      {!nodeData.readonly && (
        <Handle
          type="target"
          position={Position.Top}
          style={{
            width: 14,
            height: 14,
            background: '#fff',
            border: '2px solid #555',
            cursor: 'crosshair',
          }}
        />
      )}
      {nodeData.readonly && (
        <Handle
          type="target"
          position={Position.Top}
          style={{
            width: 0,
            height: 0,
            border: 'none',
            background: 'transparent',
            visibility: 'hidden',
          }}
        />
      )}

      {/* Status icon in top-right corner */}
      {nodeData.executionStatus && (
        <div
          style={{
            position: 'absolute',
            top: -8,
            right: -8,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            width: 24,
            height: 24,
            background: '#fff',
            borderRadius: '50%',
            border: '1px solid #ddd',
          }}
        >
          {getStatusIcon(nodeData.executionStatus)}
        </div>
      )}

      <div style={{ fontWeight: 500, marginBottom: nodeData.duration ? 4 : 0 }}>
        {nodeData.label}
      </div>

      {/* Duration badge */}
      {nodeData.duration && (
        <div
          style={{
            fontSize: 11,
            color: '#666',
            fontFamily: 'monospace',
            marginBottom: 4,
          }}
        >
          {nodeData.duration}
        </div>
      )}

      {/* Execution status text */}
      {nodeData.executionStatus &&
        nodeData.executionStatus !== 'NOT_EXECUTED' && (
          <div
            style={{
              fontSize: 11,
              color: nodeData.executionStatus === 'FAILED' ? '#ff4d4f' : '#666',
              fontWeight: 500,
            }}
          >
            {nodeData.executionStatus === 'COMPLETED' && 'Completed'}
            {nodeData.executionStatus === 'RUNNING' && 'Running...'}
            {nodeData.executionStatus === 'FAILED' && 'Failed'}
            {nodeData.executionStatus === 'PENDING' && 'Pending'}
          </div>
        )}

      {!nodeData.readonly && (
        <Handle
          type="source"
          position={Position.Bottom}
          style={{
            width: 14,
            height: 14,
            background: '#fff',
            border: '2px solid #555',
            cursor: 'crosshair',
          }}
        />
      )}
      {nodeData.readonly && (
        <Handle
          type="source"
          position={Position.Bottom}
          style={{
            width: 0,
            height: 0,
            border: 'none',
            background: 'transparent',
            visibility: 'hidden',
          }}
        />
      )}
    </div>
  );
});

ExecutionStatusNode.displayName = 'ExecutionStatusNode';
