import {
  CircleCheck,
  CircleDashed,
  CircleHelp,
  CircleOff,
  CirclePause,
  CircleX,
} 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'

/**
 * Estado de acceso a una propiedad de Search Console.
 *
 * Icono **más** palabra, siempre (RT-04). El color es refuerzo: en escala de
 * grises, o para quien no distingue el verde del rojo, los cinco estados tienen
 * que seguir diferenciándose. Un estado que se comunica sólo por color no se
 * comunica.
 *
 * La palabra y su ayuda no están acá: están en el catálogo, bajo
 * `access.<ESTADO>.label` y `.help`. Este mapa se arma al importar el módulo
 * —antes de que el catálogo esté instalado— así que lo único que puede guardar
 * es lo que no depende del idioma: el icono y el tono.
 */
const ACCESS_STATES: Record<string, { icon: LucideIcon; tone: StatusTone }> = {
  AWAITING_ACCESS: {
    icon: CircleDashed,
    // Falta una acción tuya, y ésa es la definición del tono: no es una falla
    // del sistema ni un estado que se resuelva solo con esperar.
    tone: 'attention',
  },
  OPERATIONAL: {
    icon: CircleCheck,
    tone: 'positive',
  },
  ACCESS_LOST: {
    icon: CircleX,
    tone: 'critical',
  },
  ACCESS_REVOKED: {
    icon: CircleOff,
    tone: 'critical',
  },
  SUSPENDED: {
    icon: CirclePause,
    tone: 'neutral',
  },
}

interface Props {
  state: string
  /**
   * Cuando la cuenta no puede operar, ningún dominio se presenta como operativo
   * aunque su propio estado lo diga (RT-18). El estado del dominio describe su
   * propiedad; el de la cuenta, si tenemos con qué consultarla.
   */
  canOperate?: boolean
}

/**
 * Lo que se dice de un dominio cuando la cuenta no puede consultar Google.
 *
 * Sin credencial que sirva, ningún estado del dominio es de ahora: es lo último
 * que alcanzamos a leer. Presentarlo igual que un estado vigente le atribuye al
 * dominio un problema que es de la cuenta, y manda a Search Console a resolver
 * algo que ahí no se arregla (RT-18).
 */
function withoutCredential(): string {
  return t('access.withoutCredential')
}

export function AccessStateBadge({ state, canOperate = true }: Props) {
  const definition = ACCESS_STATES[state]

  if (!definition) {
    return (
      <StatusBadge tone="neutral" icon={CircleHelp}>
        {state}
      </StatusBadge>
    )
  }

  if (state === 'OPERATIONAL' && !canOperate) {
    // La única etiqueta que sí cambia, y por un motivo que no es de forma:
    // «Operativo» es una afirmación sobre ahora, y sin credencial no hay ningún
    // ahora que podamos afirmar. Los demás estados describen algo que pasó y
    // siguen siendo ciertos, así que conservan su palabra.
    return (
      <StatusBadge tone="unknown" icon={CirclePause} help={withoutCredential()}>
        {t('access.onHold')}
      </StatusBadge>
    )
  }

  return (
    // Sin credencial la insignia conserva su etiqueta —el estado que trae es
    // información real— pero baja el tono: un rojo de alarma sobre algo que hoy
    // no podemos confirmar apura una acción que no va a cambiar nada. `unknown`
    // dice exactamente eso, y es el tono que el contrato reserva para un estado
    // que no pudimos verificar.
    <StatusBadge
      tone={canOperate ? definition.tone : 'unknown'}
      icon={definition.icon}
      help={canOperate ? accessStateHelp(state) : withoutCredential()}
    >
      {accessStateLabel(state)}
    </StatusBadge>
  )
}

/**
 * El tono que le toca a un estado de acceso.
 *
 * Sale de acá y no de un mapa propio en cada pieza: el punto de atención del
 * tablero y el badge de la ficha tienen que decir lo mismo, y con dos criterios
 * escritos por separado el punto puede quedar verde al lado de una palabra que
 * dice «acceso perdido». Incluye la regla de `canOperate`, que es justo la que
 * se olvida al copiar el mapa.
 */
export function accessStateTone(state: string, canOperate = true): StatusTone {
  const definition = ACCESS_STATES[state]
  if (!definition) return 'neutral'
  if (!canOperate) return 'unknown'
  return definition.tone
}

export function accessStateHelp(state: string, canOperate = true): string {
  if (!canOperate) return withoutCredential()
  if (!ACCESS_STATES[state]) return ''
  return t(`access.${state}.help` as TranslationKey)
}

/**
 * La etiqueta del estado, para donde no va un badge.
 *
 * La usan los filtros del listado, y sale de acá y no de la etiqueta que manda
 * el servidor a propósito: si el botón dijera «Esperando autorización» y la fila
 * «Esperando acceso», parecerían dos cosas distintas y filtrar por una dejaría
 * en pantalla la otra.
 */
export function accessStateLabel(state: string): string {
  if (!ACCESS_STATES[state]) return state
  return t(`access.${state}.label` as TranslationKey)
}
