'use client'

import { useEffect, useState } from 'react'
import { useTranslations } from 'next-intl'
import { Link } from '@/i18n/navigation'

// ---------------------------------------------------------------------------
// API de consentimiento de Cloudflare Zaraz (se inyecta cuando el dominio pasa
// por el proxy de Cloudflare con Zaraz Consent activado).
// ---------------------------------------------------------------------------
interface ZarazConsent {
  modal?: boolean
  APIReady?: boolean
  setAll?: (status: boolean) => void
  getAll?: () => Record<string, boolean>
  sendQueuedEvents?: () => void
}
declare global {
  interface Window {
    zaraz?: { consent?: ZarazConsent }
    UWCookies?: {
      showBanner: () => void
      revokeConsent: () => void
      acceptAll: () => void
      rejectAll: () => void
    }
  }
}

// Categorías de consentimiento (necesarias siempre activas).
type Category = { key: string; label: string; always?: boolean; desc?: string }
export const CONSENT_CATEGORIES: readonly Category[] = [
  { key: 'necessary', label: 'Necesarias', always: true, desc: 'Esenciales para el funcionamiento del sitio. No se pueden desactivar.' },
  { key: 'analytics', label: 'Analíticas', desc: 'Nos ayudan a entender cómo usas el sitio para mejorarlo.' },
  { key: 'marketing', label: 'Marketing', desc: 'Se utilizan para mostrarte anuncios relevantes.' },
]

type Consent = Record<string, boolean>
const CONSENT_COOKIE = 'ns_cookie_consent'
const CONSENT_EVENT = 'ns:consentchange'
const SHOW_EVENT = 'ns:showbanner'

function zaraz(): ZarazConsent | undefined {
  return typeof window !== 'undefined' ? window.zaraz?.consent : undefined
}

/** Lee la preferencia guardada en la cookie ns_cookie_consent. */
function readConsent(): Consent | null {
  if (typeof document === 'undefined') return null
  const m = document.cookie.match(/(?:^|; )ns_cookie_consent=([^;]*)/)
  if (!m) return null
  try {
    return JSON.parse(decodeURIComponent(m[1])) as Consent
  } catch {
    return null
  }
}

function writeConsent(c: Consent) {
  const maxAge = 60 * 60 * 24 * 365 // 1 año
  document.cookie = `${CONSENT_COOKIE}=${encodeURIComponent(JSON.stringify(c))}; path=/; max-age=${maxAge}; SameSite=Lax`
  // Sincroniza con Cloudflare Zaraz si está presente (control granular real lo
  // gestiona el panel de Zaraz; aquí aplicamos aceptar/rechazar todo).
  const nonNecessary = CONSENT_CATEGORIES.some((cat) => !cat.always && c[cat.key])
  zaraz()?.setAll?.(nonNecessary)
  zaraz()?.sendQueuedEvents?.()
  window.dispatchEvent(new CustomEvent(CONSENT_EVENT))
}

function allFlags(value: boolean): Consent {
  const c: Consent = {}
  for (const cat of CONSENT_CATEGORIES) c[cat.key] = cat.always ? true : value
  return c
}

function acceptAll() {
  writeConsent(allFlags(true))
}
function rejectAll() {
  writeConsent(allFlags(false))
}
function showBanner() {
  window.dispatchEvent(new CustomEvent(SHOW_EVENT))
}
function revokeConsent() {
  // Borra la cookie, retira en Zaraz y reabre el banner.
  document.cookie = `${CONSENT_COOKIE}=; path=/; max-age=0; SameSite=Lax`
  zaraz()?.setAll?.(false)
  window.dispatchEvent(new CustomEvent(CONSENT_EVENT))
  showBanner()
}

/**
 * ¿Ha aceptado el usuario esta categoría de cookies? Reacciona en caliente al
 * banner (`writeConsent`/`revokeConsent` disparan `ns:consentchange`), así que
 * quien la use se entera de aceptar o revocar sin recargar.
 *
 * Arranca en `false` a propósito: en el servidor no hay cookie que leer, y hasta
 * que no se confirme el consentimiento NO debe cargarse nada de la categoría.
 */
export function useConsent(category: string): boolean {
  const [granted, setGranted] = useState(false)

  useEffect(() => {
    const sync = () => setGranted(!!readConsent()?.[category])
    sync()
    window.addEventListener(CONSENT_EVENT, sync)
    return () => window.removeEventListener(CONSENT_EVENT, sync)
  }, [category])

  return granted
}

// ---------------------------------------------------------------------------
// Banner de consentimiento (fijo abajo, en todo el sitio).
// ---------------------------------------------------------------------------
export function CookieBanner() {
  const t = useTranslations('UI')
  const [visible, setVisible] = useState(false)
  const [details, setDetails] = useState(false)
  // Estado de los checkboxes granulares (categorías no necesarias).
  const [prefs, setPrefs] = useState<Consent>({ analytics: false, marketing: false })

  useEffect(() => {
    window.UWCookies = { showBanner, revokeConsent, acceptAll, rejectAll }
    // Precarga los checkboxes con lo ya guardado (si lo hay).
    // El lint avisa de que esto encadena un render, y aquí no hay alternativa:
    // el consentimiento está en una cookie del navegador y en el servidor no
    // existe, así que no se puede saber al renderizar sin romper la hidratación
    // (saldría el banner en el HTML a quien ya había decidido). El render de más
    // es inherente y solo ocurre al montar.
    /* eslint-disable react-hooks/set-state-in-effect */
    const saved = readConsent()
    if (saved) setPrefs({ analytics: !!saved.analytics, marketing: !!saved.marketing })
    else setVisible(true) // Aparece si aún no hay decisión guardada.
    /* eslint-enable react-hooks/set-state-in-effect */
    const onShow = () => {
      const cur = readConsent()
      if (cur) setPrefs({ analytics: !!cur.analytics, marketing: !!cur.marketing })
      setDetails(false)
      setVisible(true)
    }
    const onChange = () => {
      if (readConsent()) setVisible(false)
    }
    window.addEventListener(SHOW_EVENT, onShow)
    window.addEventListener(CONSENT_EVENT, onChange)
    return () => {
      window.removeEventListener(SHOW_EVENT, onShow)
      window.removeEventListener(CONSENT_EVENT, onChange)
    }
  }, [])

  if (!visible) return null

  function savePrefs() {
    writeConsent({ necessary: true, analytics: !!prefs.analytics, marketing: !!prefs.marketing })
    setVisible(false)
  }

  return (
    <div className="ns-cookie-content" role="dialog" aria-label={t('cookie.dialogLabel')}>
      <div className="ns-cookie-text">
        <h3>{t('cookie.title')}</h3>
        <p>{t('cookie.description')}</p>
        <Link href="/cookies" className="ns-cookie-link">{t('cookie.policyLink')}</Link>

        {details && (
          <div className="ns-cookie-details" style={{ display: 'block' }}>
            <div className="ns-cookie-category">
              <label>
                <input type="checkbox" checked disabled readOnly />
                <span className="ns-cookie-cat-name">{t('cookie.catNecessary')}</span>
              </label>
              <p>{t('cookie.descNecessary')}</p>
            </div>
            <div className="ns-cookie-category">
              <label>
                <input type="checkbox" id="ns-cookie-analytics" checked={!!prefs.analytics} onChange={(e) => setPrefs((s) => ({ ...s, analytics: e.target.checked }))} />
                <span className="ns-cookie-cat-name">{t('cookie.catAnalytics')}</span>
              </label>
              <p>{t('cookie.descAnalytics')}</p>
            </div>
            <div className="ns-cookie-category">
              <label>
                <input type="checkbox" id="ns-cookie-marketing" checked={!!prefs.marketing} onChange={(e) => setPrefs((s) => ({ ...s, marketing: e.target.checked }))} />
                <span className="ns-cookie-cat-name">{t('cookie.catMarketing')}</span>
              </label>
              <p>{t('cookie.descMarketing')}</p>
            </div>
            <div className="ns-cookie-actions-detail">
              <button type="button" className="ns-cookie-btn ns-cookie-btn-save" data-action="save" onClick={savePrefs}>{t('cookie.savePrefs')}</button>
            </div>
          </div>
        )}
      </div>
      <div className="ns-cookie-actions">
        <button type="button" className="ns-cookie-btn ns-cookie-btn-reject" data-action="reject" onClick={() => { rejectAll(); setVisible(false) }}>{t('cookie.reject')}</button>
        <button type="button" className="ns-cookie-btn ns-cookie-btn-customize" data-action="customize" onClick={() => setDetails((v) => !v)}>{t('cookie.customize')}</button>
        <button type="button" className="ns-cookie-btn ns-cookie-btn-accept" data-action="accept" onClick={() => { acceptAll(); setVisible(false) }}>{t('cookie.acceptAll')}</button>
      </div>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Botones «Cambiar / Retirar consentimiento» de la página /cookies.
// ---------------------------------------------------------------------------
export function CookieConsentButtons() {
  const t = useTranslations('UI')
  useEffect(() => {
    window.UWCookies = { showBanner, revokeConsent, acceptAll, rejectAll }
  }, [])
  return (
    <div className="ns-consent-buttons">
      <button type="button" onClick={showBanner} className="btn-ns btn-ns-form">
        {t('cookie.changeConsent')}
      </button>
      <button type="button" onClick={revokeConsent} className="btn-ns btn-ns-form btn-ns-secondary">
        {t('cookie.revokeConsent')}
      </button>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Panel «Tu estado de consentimiento»: muestra los datos de la API de Zaraz
// (o, si Zaraz no está, la preferencia guardada en la cookie ns_cookie_consent).
// ---------------------------------------------------------------------------
export function ConsentStatus() {
  const t = useTranslations('UI')
  const [state, setState] = useState<{ source: string; values: Consent | null }>({
    source: 'cookie',
    values: null,
  })

  useEffect(() => {
    function refresh() {
      const c = zaraz()
      if (c?.APIReady && c.getAll) {
        setState({ source: 'zaraz', values: c.getAll() })
      } else {
        setState({ source: 'cookie', values: readConsent() })
      }
    }
    refresh()
    window.addEventListener(CONSENT_EVENT, refresh)
    window.addEventListener('zarazConsentAPIReady', refresh)
    window.addEventListener('zarazConsentChoicesUpdated', refresh)
    return () => {
      window.removeEventListener(CONSENT_EVENT, refresh)
      window.removeEventListener('zarazConsentAPIReady', refresh)
      window.removeEventListener('zarazConsentChoicesUpdated', refresh)
    }
  }, [])

  const zarazData = state.source === 'zaraz' && state.values
  const values = state.values
  const catLabel: Record<string, string> = {
    necessary: t('cookie.catNecessary'),
    analytics: t('cookie.catAnalytics'),
    marketing: t('cookie.catMarketing'),
  }

  return (
    <div className="ns-consent-status">
      <p className="ns-consent-source">
        {zarazData
          ? t('cookie.statusZaraz')
          : values
            ? t('cookie.statusSaved')
            : t('cookie.statusUnavailable')}
      </p>
      <ul>
        {zarazData ? (
          // Datos en vivo de la API de Zaraz: cada propósito y su estado.
          Object.entries(values as Consent).map(([purpose, granted]) => (
            <li key={purpose}>
              <span>{purpose}</span>
              <span className={granted ? 'ns-consent-on' : 'ns-consent-off'}>
                {granted ? t('cookie.accepted') : t('cookie.rejected')}
              </span>
            </li>
          ))
        ) : (
          // Categorías locales (cookie ns_cookie_consent).
          CONSENT_CATEGORIES.map((cat) => {
            const on = cat.always || Boolean(values?.[cat.key])
            return (
              <li key={cat.key}>
                <span>{catLabel[cat.key] ?? cat.label}</span>
                <span className={cat.always ? 'ns-consent-always' : on ? 'ns-consent-on' : 'ns-consent-off'}>
                  {cat.always ? t('cookie.alwaysOn') : values ? (on ? t('cookie.accepted') : t('cookie.rejected')) : '—'}
                </span>
              </li>
            )
          })
        )}
      </ul>
    </div>
  )
}
