import {
  CircleCheck,
  CircleDotDashed,
  CircleHelp,
  CircleX,
  FilePen,
  Hourglass,
  LoaderCircle,
} from 'lucide-react'
import type { LucideIcon } from 'lucide-react'

import { StatusBadge } from '@/components/StatusBadge'
import type { StatusTone } from '@/components/StatusBadge'
import { t } from '@/lib/i18n'
import type { TranslationKey } from '@/lib/i18n'
import { cn } from '@/lib/utils'

/**
 * Estado de un lote de trabajo.
 *
 * `COMPLETED` y `PARTIAL` llevan iconos de silueta distinta, no la misma tilde
 * con otro color (R-C, RT-04). Un lote que se cortó por cuota dejó URLs sin
 * consultar: si en la lista se ve igual que uno terminado, la persona lee una
 * foto parcial del sitio como si fuera el sitio entero, que es justo lo que el
 * producto no puede afirmar. La prueba es mirar la pantalla en escala de
 * grises: ahí el color no ayuda y los cinco estados tienen que seguir
 * distinguiéndose.
 *
 * La palabra y su ayuda viven en el catálogo, bajo `batch.<ESTADO>.label` y
 * `.help`: este mapa se arma al importar, que es antes de que haya catálogo.
 */
const BATCH_STATES: Record<
  string,
  {
    icon: LucideIcon
    tone: StatusTone
    className?: string
  }
> = {
  DRAFT: {
    icon: FilePen,
    // El tono de «todavía no preguntamos» sirve igual para «todavía no salió»:
    // el borde punteado dice que esto no ocurrió, y es exactamente lo que hay
    // que decir de un borrador. Teñirlo de neutro lo dejaría a un color de
    // «encolado», que es el estado que sí va a correr solo.
    tone: 'unknown',
  },
  QUEUED: {
    icon: Hourglass,
    tone: 'neutral',
  },
  RUNNING: {
    icon: LoaderCircle,
    tone: 'neutral',
    // El icono gira desde acá porque `StatusBadge` recibe un icono, no una
    // animación: el único estado del producto que se dibuja en movimiento es
    // éste, y el movimiento es parte de lo que significa «en curso».
    className: '[&>svg]:animate-spin motion-reduce:[&>svg]:animate-none',
  },
  COMPLETED: {
    icon: CircleCheck,
    tone: 'positive',
  },
  PARTIAL: {
    icon: CircleDotDashed,
    // Ni la familia de «terminado» ni la de «falló»: es su propio resultado.
    // Teñirlo como cualquiera de las otras dos lo convierte en algo que no es.
    // Por eso `attention` y no `positive`, y por eso el icono tiene silueta
    // propia: en escala de grises es lo único que lo separa de «Completado».
    tone: 'attention',
  },
  FAILED: {
    icon: CircleX,
    tone: 'critical',
  },
}

interface Props {
  state: string
  /**
   * El motivo en una frase, cuando el lote lo tiene.
   *
   * En el badge sólo reemplaza al texto de ayuda: un badge con una oración
   * adentro rompe la fila de la tabla. Donde el motivo tiene que **verse** —el
   * encabezado de la ficha del lote— va `BatchStateHeadline`, que lo pone en el
   * mismo bloque que el estado y no al pie.
   */
  reason?: string | null
  className?: string
}

export function BatchStateBadge({ state, reason, className }: Props) {
  const definition = BATCH_STATES[state]

  if (!definition) {
    // Un estado que no conocemos igual se dibuja con icono y palabra: un badge
    // que sólo trae una sigla es un estado que no se distingue de ningún otro.
    return (
      <StatusBadge tone="neutral" icon={CircleHelp} className={className}>
        {state}
      </StatusBadge>
    )
  }

  return (
    <StatusBadge
      tone={definition.tone}
      icon={definition.icon}
      help={reason?.trim() || batchStateHelp(state)}
      className={cn(definition.className, className)}
    >
      {batchStateLabel(state)}
    </StatusBadge>
  )
}

/**
 * El estado y su motivo, juntos y en una sola línea (V10).
 *
 * «Parcial — se agotó el cupo del día» responde la pregunta entera; el estado
 * solo deja a la persona buscando el porqué en otro lado de la pantalla.
 */
export function BatchStateHeadline({ state, reason, className }: Props) {
  const reasonText = reason?.trim() || batchStateHelp(state)

  return (
    <div className={cn('flex flex-wrap items-baseline gap-x-2 gap-y-1', className)}>
      <BatchStateBadge state={state} />
      {reasonText ? (
        <p className="text-sm text-pretty">
          {/* La raya une las dos mitades en una sola frase —«Parcial — se agotó
              el cupo del día»— sin que el lector de pantalla lea un guion suelto
              entre el estado y su motivo. */}
          <span aria-hidden>— </span>
          {reasonText}
        </p>
      ) : null}
    </div>
  )
}

export function batchStateLabel(state: string): string {
  if (!BATCH_STATES[state]) return state
  return t(`batch.${state}.label` as TranslationKey)
}

export function batchStateHelp(state: string): string {
  if (!BATCH_STATES[state]) return ''
  return t(`batch.${state}.help` as TranslationKey)
}
