import type { ReactNode } from 'react'
import { Play, Cog, Square, Diamond, AlertTriangle, EllipsisVertical } from 'lucide-react'
import styles from './RouteFlow.module.css'
import { Dropdown } from '../Dropdown/Dropdown'
import { formatDuration } from '../../../utils/format-utils'

export interface NodeBadge {
  label: string
  variant?: 'info' | 'success' | 'warning' | 'error'
  onClick?: () => void
}

export interface RouteNode {
  name: string
  type: 'from' | 'process' | 'to' | 'choice' | 'error-handler'
  durationMs: number
  status: 'ok' | 'slow' | 'fail'
  isBottleneck?: boolean
  badges?: NodeBadge[]
}

export interface NodeAction {
  label: string
  icon?: ReactNode
  onClick: () => void
  disabled?: boolean
  divider?: boolean
}

export interface FlowSegment {
  label: string
  nodes: RouteNode[]
  variant?: 'default' | 'error' | 'warning' | 'info'
}

interface RouteFlowProps {
  nodes?: RouteNode[]
  flows?: FlowSegment[]
  onNodeClick?: (node: RouteNode, index: number) => void
  selectedIndex?: number
  actions?: NodeAction[]
  getActions?: (node: RouteNode, index: number) => NodeAction[]
  className?: string
}

function durationClass(ms: number, status: string): string {
  if (status === 'fail') return styles.durBreach
  if (ms < 50) return styles.durFast
  if (ms < 150) return styles.durNormal
  if (ms < 300) return styles.durSlow
  return styles.durBreach
}

const TYPE_ICONS: Record<string, ReactNode> = {
  'from': <Play size={14} />,
  'process': <Cog size={14} />,
  'to': <Square size={14} />,
  'choice': <Diamond size={14} />,
  'error-handler': <AlertTriangle size={14} />,
}

const ICON_CLASSES: Record<string, string> = {
  'from': styles.iconFrom,
  'process': styles.iconProcess,
  'to': styles.iconTo,
  'choice': styles.iconChoice,
  'error-handler': styles.iconErrorHandler,
}

function nodeStatusClass(node: RouteNode): string {
  if (node.isBottleneck) return styles.nodeBottleneck
  if (node.status === 'fail') return styles.nodeError
  if (node.status === 'slow') return styles.nodeSlow
  return styles.nodeHealthy
}

function renderActionTrigger(
  node: RouteNode,
  index: number,
  isSelected: boolean,
  actions?: NodeAction[],
  getActions?: (node: RouteNode, index: number) => NodeAction[],
) {
  const resolvedActions = getActions ? getActions(node, index) : (actions ?? [])
  if (resolvedActions.length === 0) return null
  return (
    <div
      className={`${styles.actionsTrigger} ${isSelected ? styles.actionsVisible : ''}`}
      onClick={(e) => e.stopPropagation()}
      onKeyDown={(e) => e.stopPropagation()}
    >
      <Dropdown
        trigger={
          <button
            className={styles.actionsBtn}
            aria-label={`Actions for ${node.name}`}
            type="button"
          >
            <EllipsisVertical size={14} />
          </button>
        }
        items={resolvedActions}
      />
    </div>
  )
}

const FLOW_LABEL_CLASSES: Record<string, string> = {
  'default': styles.flowLabelDefault,
  'error': styles.flowLabelError,
  'warning': styles.flowLabelWarning,
  'info': styles.flowLabelInfo,
}

function renderNodeChain(
  nodes: RouteNode[],
  globalIndexOffset: number,
  onNodeClick?: RouteFlowProps['onNodeClick'],
  selectedIndex?: number,
  actions?: NodeAction[],
  getActions?: (node: RouteNode, index: number) => NodeAction[],
) {
  const isClickable = !!onNodeClick

  return nodes.map((node, i) => {
    const globalIndex = globalIndexOffset + i
    const isSelected = selectedIndex === globalIndex

    return (
      <div key={i} className={styles.nodeWrapper}>
        {i > 0 && (
          <div className={styles.connector}>
            <div className={styles.connectorLine} />
            <div className={styles.connectorArrow} />
          </div>
        )}
        <div
          className={`${styles.node} ${nodeStatusClass(node)} ${isSelected ? styles.nodeSelected : ''} ${isClickable ? styles.nodeClickable : ''}`}
          onClick={() => onNodeClick?.(node, globalIndex)}
          role={isClickable ? 'button' : undefined}
          tabIndex={isClickable ? 0 : undefined}
          onKeyDown={(e) => {
            if (isClickable && (e.key === 'Enter' || e.key === ' ')) {
              e.preventDefault()
              onNodeClick?.(node, globalIndex)
            }
          }}
        >
          {(node.isBottleneck || node.badges?.length) ? (
            <span className={styles.badgeRow}>
              {node.isBottleneck && <span className={`${styles.badge} ${styles.badgeError}`}>BOTTLENECK</span>}
              {node.badges?.map((badge, bi) => (
                <span
                  key={bi}
                  className={`${styles.badge} ${styles[`badge${(badge.variant ?? 'info').charAt(0).toUpperCase()}${(badge.variant ?? 'info').slice(1)}`] ?? styles.badgeInfo}`}
                  onClick={badge.onClick ? (e) => { e.stopPropagation(); badge.onClick!() } : undefined}
                  style={badge.onClick ? { cursor: 'pointer' } : undefined}
                >
                  {badge.label}
                </span>
              ))}
            </span>
          ) : null}
          <div className={`${styles.icon} ${ICON_CLASSES[node.type] ?? styles.iconTo}`}>
            {TYPE_ICONS[node.type] ?? <Square size={14} />}
          </div>
          <div className={styles.info}>
            <div className={styles.type}>{node.type}</div>
            <div className={styles.label} title={node.name}>{node.name}</div>
          </div>
          <div className={styles.stats}>
            <div className={`${styles.duration} ${durationClass(node.durationMs, node.status)}`}>
              {formatDuration(node.durationMs)}
            </div>
          </div>
          {renderActionTrigger(node, globalIndex, isSelected, actions, getActions)}
        </div>
      </div>
    )
  })
}

export function RouteFlow({ nodes, flows, onNodeClick, selectedIndex, actions, getActions, className }: RouteFlowProps) {
  // Multi-flow mode
  if (flows && flows.length > 0) {
    let globalOffset = 0
    return (
      <div className={`${styles.wrapper} ${className ?? ''}`}>
        {flows.map((flow, fi) => {
          const sectionOffset = globalOffset
          globalOffset += flow.nodes.length
          const variant = flow.variant ?? 'default'
          const labelClass = FLOW_LABEL_CLASSES[variant] ?? styles.flowLabelDefault
          return (
            <div key={fi} className={`${styles.flowSection} ${fi > 0 ? styles.flowSectionSeparated : ''}`}>
              <div className={`${styles.flowLabel} ${labelClass}`}>{flow.label}</div>
              {renderNodeChain(flow.nodes, sectionOffset, onNodeClick, selectedIndex, actions, getActions)}
            </div>
          )
        })}
      </div>
    )
  }

  // Legacy mode (single nodes array with automatic error-handler separation)
  const allNodes = nodes ?? []
  const mainNodes = allNodes.filter((n) => n.type !== 'error-handler')
  const errorHandlers = allNodes.filter((n) => n.type === 'error-handler')

  // Map from mainNodes index back to original nodes index
  const mainNodeOriginalIndices = allNodes.reduce<number[]>((acc, n, idx) => {
    if (n.type !== 'error-handler') acc.push(idx)
    return acc
  }, [])

  return (
    <div className={`${styles.wrapper} ${className ?? ''}`}>
      {mainNodes.map((node, i) => {
        const originalIndex = mainNodeOriginalIndices[i]
        const isSelected = selectedIndex === originalIndex
        const isClickable = !!onNodeClick

        return (
          <div key={i} className={styles.nodeWrapper}>
            {i > 0 && (
              <div className={styles.connector}>
                <div className={styles.connectorLine} />
                <div className={styles.connectorArrow} />
              </div>
            )}
            <div
              className={`${styles.node} ${nodeStatusClass(node)} ${isSelected ? styles.nodeSelected : ''} ${isClickable ? styles.nodeClickable : ''}`}
              onClick={() => onNodeClick?.(node, originalIndex)}
              role={isClickable ? 'button' : undefined}
              tabIndex={isClickable ? 0 : undefined}
              onKeyDown={(e) => {
                if (isClickable && (e.key === 'Enter' || e.key === ' ')) {
                  e.preventDefault()
                  onNodeClick?.(node, originalIndex)
                }
              }}
            >
              {(node.isBottleneck || node.badges?.length) ? (
                <span className={styles.badgeRow}>
                  {node.isBottleneck && <span className={`${styles.badge} ${styles.badgeError}`}>BOTTLENECK</span>}
                  {node.badges?.map((badge, bi) => (
                    <span
                      key={bi}
                      className={`${styles.badge} ${styles[`badge${(badge.variant ?? 'info').charAt(0).toUpperCase()}${(badge.variant ?? 'info').slice(1)}`] ?? styles.badgeInfo}`}
                      onClick={badge.onClick ? (e) => { e.stopPropagation(); badge.onClick!() } : undefined}
                      style={badge.onClick ? { cursor: 'pointer' } : undefined}
                    >
                      {badge.label}
                    </span>
                  ))}
                </span>
              ) : null}
              <div className={`${styles.icon} ${ICON_CLASSES[node.type] ?? styles.iconTo}`}>
                {TYPE_ICONS[node.type] ?? <Square size={14} />}
              </div>
              <div className={styles.info}>
                <div className={styles.type}>{node.type}</div>
                <div className={styles.label} title={node.name}>{node.name}</div>
              </div>
              <div className={styles.stats}>
                <div className={`${styles.duration} ${durationClass(node.durationMs, node.status)}`}>
                  {formatDuration(node.durationMs)}
                </div>
              </div>
              {renderActionTrigger(node, originalIndex, isSelected, actions, getActions)}
            </div>
          </div>
        )
      })}

      {errorHandlers.length > 0 && (
        <div className={styles.errorSection}>
          <div className={styles.errorLabel}>Error Handler</div>
          {errorHandlers.map((node, i) => {
            const errOriginalIndex = allNodes.indexOf(node)
            return (
              <div key={i} className={`${styles.node} ${styles.nodeError}`}>
                <div className={`${styles.icon} ${styles.iconErrorHandler}`}>
                  {TYPE_ICONS['error-handler']}
                </div>
                <div className={styles.info}>
                  <div className={styles.type}>{node.type}</div>
                  <div className={styles.label} title={node.name}>{node.name}</div>
                </div>
                <div className={styles.stats}>
                  <div className={`${styles.duration} ${durationClass(node.durationMs, node.status)}`}>
                    {formatDuration(node.durationMs)}
                  </div>
                </div>
                {renderActionTrigger(node, errOriginalIndex, false, actions, getActions)}
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}
