/**
 * PhaseProgress — horizontal phase-step strip with connector lines.
 * @countermeasure-platform/web-components/primitives/phase-progress
 *
 * Renders one filled circle + label per declared phase, joined by a
 * connector line. Status colors key off the `status` of the run + the
 * position of `currentPhase` within `phases`:
 *   - phases before currentPhase → "completed" (filled)
 *   - the currentPhase           → reflects `status` (running/failed/...)
 *   - phases after currentPhase  → "pending"
 *
 * Token-driven via the shadcn-compat tokens (`bg-primary`, `bg-muted`,
 * `text-muted-foreground`, `bg-success`, `bg-destructive`, `bg-warning`)
 * so it themes alongside the host app.
 */

import * as React from 'react'
import { cn } from '../react/primitives/utils'

export type PhaseProgressStatus = 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'

export interface PhaseProgressPhase {
  key: string
  label: string
}

export interface PhaseProgressProps extends React.HTMLAttributes<HTMLDivElement> {
  phases: PhaseProgressPhase[]
  currentPhase: string
  status: PhaseProgressStatus
}

type PhaseState =
  | 'completed'
  | 'current-running'
  | 'current-failed'
  | 'current-cancelled'
  | 'pending'

function classifyPhase(
  index: number,
  currentIndex: number,
  status: PhaseProgressStatus
): PhaseState {
  if (currentIndex === -1) {
    // Unknown current phase — treat all as pending unless the run is done.
    if (status === 'completed') return 'completed'
    return 'pending'
  }
  if (index < currentIndex) return 'completed'
  if (index > currentIndex) {
    return status === 'completed' ? 'completed' : 'pending'
  }
  // index === currentIndex
  switch (status) {
    case 'running':
      return 'current-running'
    case 'completed':
      return 'completed'
    case 'failed':
      return 'current-failed'
    case 'cancelled':
      return 'current-cancelled'
    case 'queued':
    default:
      return 'pending'
  }
}

const dotByState: Record<PhaseState, string> = {
  completed: 'bg-primary text-primary-foreground border-primary',
  'current-running': 'bg-primary text-primary-foreground border-primary animate-pulse',
  'current-failed': 'bg-destructive text-destructive-foreground border-destructive',
  'current-cancelled': 'bg-warning text-warning-foreground border-warning',
  pending: 'bg-muted text-muted-foreground border-border',
}

const connectorByState: Record<'completed' | 'pending', string> = {
  completed: 'bg-primary',
  pending: 'bg-border',
}

const labelByState: Record<PhaseState, string> = {
  completed: 'text-foreground',
  'current-running': 'text-foreground font-medium',
  'current-failed': 'text-destructive font-medium',
  'current-cancelled': 'text-warning font-medium',
  pending: 'text-muted-foreground',
}

export function PhaseProgress({
  phases,
  currentPhase,
  status,
  className,
  ...rest
}: PhaseProgressProps) {
  const currentIndex = phases.findIndex(p => p.key === currentPhase)

  return (
    <div
      data-slot="phase-progress"
      data-status={status}
      className={cn('flex w-full items-start', className)}
      {...rest}
    >
      {phases.map((phase, index) => {
        const state = classifyPhase(index, currentIndex, status)
        const isLast = index === phases.length - 1
        // Connector after this dot is "completed" iff the next phase has
        // already started (i.e. currentIndex > index, OR run is completed).
        const connectorState: 'completed' | 'pending' =
          status === 'completed' || index < currentIndex ? 'completed' : 'pending'

        return (
          <React.Fragment key={phase.key}>
            <div className="flex min-w-0 flex-col items-center gap-1.5">
              <div
                data-slot="phase-progress-dot"
                data-state={state}
                aria-current={state.startsWith('current') ? 'step' : undefined}
                className={cn(
                  'flex h-6 w-6 items-center justify-center rounded-full border text-[10px] font-semibold tabular-nums transition-colors',
                  dotByState[state]
                )}
              >
                {index + 1}
              </div>
              <span className={cn('truncate text-xs', labelByState[state])} title={phase.label}>
                {phase.label}
              </span>
            </div>
            {!isLast && (
              <div
                aria-hidden
                data-slot="phase-progress-connector"
                data-state={connectorState}
                className={cn(
                  'mx-2 mt-3 h-0.5 flex-1 rounded-full transition-colors',
                  connectorByState[connectorState]
                )}
              />
            )}
          </React.Fragment>
        )
      })}
    </div>
  )
}
