import type { RefObject } from 'react'

import { FieldError, fieldErrorProps } from '@/components/FieldError'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { t } from '@/lib/i18n'
import type { TranslationKey } from '@/lib/i18n'

/**
 * Las dos formas de propiedad, explicadas por lo que significan.
 *
 * Sus nombres técnicos no le dicen nada a quien nunca entró a Search Console, y
 * elegir la que no es devuelve «la propiedad no existe» aunque el sitio esté
 * perfectamente dado de alta. Es el error más desconcertante del producto, así
 * que las dos opciones se explican por **cómo la dio de alta la persona**, que
 * es el único dato que puede recordar.
 *
 * Acá viven las dos que el producto sabe explicar y cómo se arma su ejemplo; el
 * texto está en el catálogo, porque este mapa se lee antes de que exista.
 */
const PROPERTY_SHAPES: Record<string, { example: (hostname: string) => string }> = {
  DOMAIN: {
    example: (hostname) => `sc-domain:${hostname || 'example.com'}`,
  },
  URL_PREFIX: {
    example: (hostname) => `https://${hostname || 'example.com'}/`,
  },
}

/**
 * Cómo va a quedar guardado el sitio.
 *
 * Es un espejo de la normalización del servidor, y existe sólo para que la
 * persona vea que escribir `https://Ejemplo.com/` no va a guardar eso. El
 * servidor sigue siendo la autoridad: si alguna vez discrepan, manda el
 * servidor y esto es un texto de más, nunca un dato distinto.
 */
export function normalizeHostname(value: string): string {
  let cleaned = value.trim().toLowerCase()
  if (cleaned.includes('//')) cleaned = cleaned.split('//')[1] ?? cleaned
  cleaned = cleaned.split('/')[0] ?? cleaned
  return cleaned.replace(/^www\./, '')
}

/** El identificador con el que Search Console va a conocer a la propiedad. */
export function propertyUriFor(hostname: string, propertyType: string): string {
  return PROPERTY_SHAPES[propertyType]?.example(hostname) ?? ''
}

interface Props {
  hostname: string
  propertyType: string
  propertyTypes: { value: string; label: string }[]
  hostnameError?: string
  propertyTypeError?: string
  onHostnameChange: (value: string) => void
  onPropertyTypeChange: (value: string) => void
  /** Para devolverle el foco al primer campo cuando el servidor rechaza (RT-17). */
  hostnameRef?: RefObject<HTMLInputElement | null>
}

/**
 * Los dos campos que definen un sitio: cuál es, y con qué forma está dado de
 * alta en Search Console.
 *
 * Vive en un componente y no en la pantalla porque lo piden **dos**: la conexión
 * —donde el sitio se conecta hoy— y el alta suelta, que sigue existiendo para el
 * día que la cuenta necesite más de uno. Escrito dos veces, la explicación de
 * las formas de propiedad se corregiría en una sola y la otra seguiría mandando
 * a elegir mal.
 *
 * No dibuja tarjeta, ni título, ni botón de envío: los dos usos los enmarcan
 * distinto —uno es una tarjeta de la conexión y el otro una pantalla entera— y
 * un componente que decidiera eso obligaría a pelearle el marco a uno de los dos.
 */
export function SiteFields({
  hostname,
  propertyType,
  propertyTypes,
  hostnameError,
  propertyTypeError,
  onHostnameChange,
  onPropertyTypeChange,
  hostnameRef,
}: Props) {
  const normalized = normalizeHostname(hostname)
  const propertyUri = propertyUriFor(normalized, propertyType)

  return (
    <div className="flex flex-col gap-6">
      <div className="flex flex-col gap-2">
        <Label htmlFor="hostname">{t('domainCreate.domain.label')}</Label>
        <Input
          id="hostname"
          name="hostname"
          ref={hostnameRef}
          type="text"
          inputMode="url"
          autoComplete="url"
          spellCheck={false}
          autoCapitalize="none"
          placeholder={t('domainCreate.domain.placeholder')}
          value={hostname}
          onChange={(event) => onHostnameChange(event.target.value)}
          {...fieldErrorProps('error-hostname', hostnameError)}
        />
        <p aria-live="polite" className="text-muted-foreground min-h-5 text-sm">
          {normalized && normalized !== hostname.trim() ? (
            <>
              {t('domainCreate.willSaveAs')}{' '}
              <code className="text-foreground bg-muted/60 rounded px-1" translate="no">
                {normalized}
              </code>
            </>
          ) : null}
        </p>
        <FieldError id="error-hostname" message={hostnameError} />
      </div>

      <div className="flex flex-col gap-3">
        {/*
          Grupo de radios y no un desplegable: las dos opciones tienen que verse
          a la vez para poder compararse. Un desplegable obliga a recordar la que
          no está en pantalla, que es justo la decisión que acá se está tomando.
        */}
        <fieldset className="flex flex-col gap-3">
          <legend className="mb-2 text-sm font-medium">{t('domainCreate.shape.title')}</legend>
          {propertyTypes.map((type) => {
            const detail = PROPERTY_SHAPES[type.value]
            const selected = propertyType === type.value
            return (
              <Label
                key={type.value}
                htmlFor={`shape-${type.value}`}
                className={`flex cursor-pointer items-start gap-3 rounded-lg border p-4 transition-colors ${
                  selected ? 'border-foreground bg-accent/40' : 'border-border hover:bg-accent/20'
                }`}
              >
                <input
                  type="radio"
                  id={`shape-${type.value}`}
                  name="property_type"
                  value={type.value}
                  checked={selected}
                  onChange={(event) => onPropertyTypeChange(event.target.value)}
                  className="accent-foreground mt-1 size-4"
                />
                <span className="flex flex-col gap-1">
                  <span className="block font-medium">
                    {detail ? t(`propertyShape.${type.value}.title` as TranslationKey) : type.label}
                  </span>
                  <span className="text-muted-foreground block text-sm font-normal">
                    {detail ? t(`propertyShape.${type.value}.when` as TranslationKey) : null}
                  </span>
                  <code
                    className="text-foreground bg-muted/60 mt-1 inline-block rounded px-1.5 py-0.5 text-xs"
                    translate="no"
                  >
                    {detail?.example('example.com')}
                  </code>
                </span>
              </Label>
            )
          })}
        </fieldset>
        <FieldError id="error-type" message={propertyTypeError} />
      </div>

      <div className="flex flex-col gap-1 border-t pt-4">
        <p className="text-muted-foreground text-sm">{t('domainCreate.willQuery')}</p>
        <p aria-live="polite">
          <code className="bg-muted rounded px-2 py-1 text-sm break-all" translate="no">
            {propertyUri}
          </code>
        </p>
      </div>
    </div>
  )
}
