import { useEffect, useRef, type JSX, type MouseEvent as ReactMouseEvent } from 'react'
import { ActionsMenu, type ActionItem } from './ActionsMenu'
import { useDeckTooltip } from './DeckTooltip'
import { formatRelativeTime } from './format'
import { IconButton } from './IconButton'
import { LiveDuration } from './LiveDuration'
import { resolveActionForFailClass, type ResolveAction } from './resolve-action'
import { safeHttpUrl } from './safe-url'
import { planStatusCategory, StatusChip } from './StatusChip'
import type { PlanTableColumnKey } from './plan-table-columns'

export interface PlanTableItem {
  runId: string
  slug: string
  title: string
  status: string
  seq?: number
  tasksCompleted: number
  tasksTotal: number
  createdDate?: string
  updatedAtMs: number | null
  runningStartedAtMs: number | null
  activeAgents: number
  failClass?: string
  attempts?: number
  needsYou?: boolean
  href: string
  additionalResolveActions?: ResolveAction[]
  alarmed?: boolean
}

export function PlanTableRow(props: {
  item: PlanTableItem
  column?: PlanTableColumnKey
  selected: boolean
  onOpen(item: PlanTableItem): void
  onAbandon?(item: PlanTableItem): void
  onResolve?(item: PlanTableItem, action: ResolveAction): void
}): JSX.Element {
  const anchorRef = useRef<HTMLDivElement>(null)
  useEffect(() => {
    if (props.column && props.column !== 'title') return
    const row = anchorRef.current?.closest('tr')
    if (!row) return
    row.dataset.testid = 'plan-table-row'
    row.dataset.runId = props.item.runId
    row.dataset.selected = props.selected ? 'true' : 'false'
    row.classList.add('cursor-pointer', 'transition-colors', props.selected ? 'bg-accent/10' : 'bg-surface')
    if (!props.selected) row.classList.add('hover:bg-surface-raised')
    const open = (event: globalThis.MouseEvent) => {
      const target = event.target
      if (target instanceof Element && target.closest('a, button, [role="menu"]')) return
      props.onOpen(props.item)
    }
    row.addEventListener('click', open)
    return () => row.removeEventListener('click', open)
  }, [props.column, props.item, props.onOpen, props.selected])

  const item = props.item
  const column = props.column ?? 'title'
  const title = item.title || item.slug
  const stopPropagation = (event: ReactMouseEvent<HTMLElement>) => event.stopPropagation()
  const createdTooltip = useDeckTooltip(item.createdDate ?? '', 'Created date')
  const hasUpdated = item.updatedAtMs !== null && Number.isFinite(item.updatedAtMs)
  const updatedIso = hasUpdated ? new Date(item.updatedAtMs!).toISOString() : ''
  const updatedTooltip = useDeckTooltip(updatedIso, 'Last recorded activity')
  const attempts = item.attempts ?? 1
  const attemptsTooltip = useDeckTooltip(`${attempts} launches of this plan collapsed into this row — newest shown`)
  const gapTooltip = useDeckTooltip('needs harness B3/B7')
  const category = planStatusCategory(item.status, item.needsYou)

  if (column === 'title') return <div ref={anchorRef} className="flex min-w-0 items-center gap-2"><div className="min-w-0 flex-1 py-1"><strong className="block truncate text-sm text-fg">{title}</strong>{item.title && <span className="block truncate font-mono text-[10px] text-fg-subtle">{item.slug}</span>}</div><a href={safeHttpUrl(item.href)} data-plan-run-link={item.runId} aria-label={`Open ${title}`} onClick={stopPropagation} className="inline-flex min-h-11 shrink-0 items-center px-1 text-[10px] font-semibold text-accent no-underline hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent">Open</a></div>
  if (column === 'status') return <span className="flex items-center gap-1"><StatusChip status={item.status} needsYou={item.needsYou} />{item.alarmed && <span data-testid="plan-run-alarmed"><StatusChip status="stalled" /></span>}</span>
  if (column === 'attempts') return attempts > 1 ? <span data-testid="plan-attempts" {...attemptsTooltip} className="rounded-md border border-border bg-surface-raised px-1 text-[10px] font-semibold tabular-nums text-fg-muted">×{attempts}</span> : <></>
  if (column === 'tasks') return <span className="tabular-nums text-fg-muted">{item.tasksCompleted}/{item.tasksTotal}</span>
  if (column === 'created') return <span className="text-fg-muted">{item.createdDate ? <time dateTime={item.createdDate} {...createdTooltip}>{item.createdDate}</time> : '—'}</span>
  if (column === 'updated') return <span className="text-fg-muted">{hasUpdated ? <time dateTime={updatedIso} {...updatedTooltip}>{formatRelativeTime(item.updatedAtMs!)}</time> : '—'}</span>
  if (column === 'runningFor') return <span className="text-fg-muted">{category === 'running' ? <LiveDuration startAtMs={item.runningStartedAtMs} /> : '—'}</span>
  if (column === 'agents') return <span className="whitespace-nowrap text-fg-muted">{item.activeAgents} {item.activeAgents === 1 ? 'agent' : 'agents'}</span>

  const visible = category === 'failed' ? [resolveActionForFailClass(item.failClass), ...(item.additionalResolveActions ?? [])].filter((action) => action.kind !== 'open-run') : []
  const menuItems: ActionItem[] = [...visible.map((action) => ({ label: action.label, onSelect: () => props.onResolve?.(item, action) })), { label: 'Abandon (soft delete)', onSelect: () => props.onAbandon?.(item), icon: <TrashIcon />, tone: 'danger', dividerAbove: true }]
  return <div className="flex items-center gap-1" onClick={stopPropagation}>{category === 'failed' && (visible.length + 1 > 2 ? <ActionsMenu items={menuItems} /> : <>{visible.map((action) => { const disabled = action.kind === 'retry' || action.kind === 'reroute'; return <span key={action.kind} {...(disabled ? gapTooltip : {})}><button type="button" aria-label={action.label} disabled={disabled} onClick={() => props.onResolve?.(item, action)} className="inline-flex min-h-11 items-center rounded-md border border-accent bg-accent px-1 text-[10px] font-semibold text-bg @min-[28rem]:px-2 disabled:cursor-not-allowed disabled:border-border disabled:bg-surface-raised disabled:text-fg-subtle">{action.label.split(' ', 1)[0]}{action.label.includes(' ') && <span className="hidden @min-[28rem]:inline">{' '}{action.label.slice(action.label.indexOf(' ') + 1)}</span>}</button></span> })}<IconButton icon={<TrashIcon />} label="Abandon (soft delete)" tooltip="Abandon — soft delete; nothing is hard-deleted" tone="danger" onClick={() => props.onAbandon?.(item)} /></>)}</div>
}

function TrashIcon(): JSX.Element { return <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8"><path d="M4 7h16M10 11v6m4-6v6M9 7l1-2h4l1 2m-9 0 1 13h10l1-13" /></svg> }
