<script setup lang="ts">
import { computed, watch } from 'vue'
import { useFavoritesStore } from '~/stores/favorites'
import { useHistoryStore } from '~/stores/history'
import type { SearchHit } from '~/types'

interface EntrelineaDoc {
  id?: string
  image?: string
  link?: string
  locale?: string
  page?: number | string
  text?: string
  [key: string]: unknown
}

const props = defineProps<{
  document: EntrelineaDoc
  /** Identificador de la colección dentro del store de favoritos.
   *  Si no se pasa, no se renderiza el botón de favorito. */
  collection?: string
  /** Versión del campo `text` con las coincidencias ya envueltas en
   *  <mark class="search-match"> por Typesense. Si viene, se usa para
   *  mostrar el cuerpo con resaltado; si no, cae al `document.text`. */
  highlightedText?: string | null
}>()

const emits = defineEmits<{ close: [] }>()

/** URL de ImageKit con preset `detail` (1800px, q90). La construcción
 *  centralizada vive en `~/utils/entrelineaImage` para no duplicarla. */
const imageUrl = computed<string | null>(() => {
  return getEntrelineaImageUrl(props.document?.image, 'detail')
})

const title = computed(() => {
  return (props.document?.id as string) || 'Entrelínea'
})

const bodyHtml = computed<string>(() => {
  return props.highlightedText || props.document?.text || ''
})

/* -------------------------------------------------------------------------- */
/*  Favoritos                                                                  */
/* -------------------------------------------------------------------------- */

const favorites = useFavoritesStore()
const history = useHistoryStore()
const toast = useToast()

/** Adapta el documento de Typesense al shape SearchHit que pide el store
 *  de favoritos/historial (que se reusa entre todos los buscadores). */
function toSearchHit(doc: EntrelineaDoc): SearchHit {
  const id = doc.id || ''
  return {
    _id: id,
    id,
    title: id || 'Entrelínea',
    body: doc.text,
    ...doc
  }
}

// Registrar la visita en el historial cada vez que cambia el documento mostrado.
// El store deduplica por (collection, id): si el usuario reabre la misma
// entrelínea, el item salta arriba y se actualiza visitedAt. No registramos
// si no nos pasaron `collection` o si el documento aún no tiene id.
watch(
  () => [props.collection, props.document?.id] as const,
  ([collection, id]) => {
    if (!collection || !id) return
    history.visit(collection, toSearchHit(props.document))
  },
  { immediate: true }
)

const isFav = computed(() => {
  if (!props.collection || !props.document?.id) return false
  return favorites.isFavorite(props.collection, props.document.id)
})

function onToggleFavorite() {
  if (!props.collection || !props.document?.id) return
  const wasFav = isFav.value
  favorites.toggle(props.collection, toSearchHit(props.document))
  toast.add({
    title: wasFav ? 'Eliminado de tu lista' : 'Guardado en tu lista',
    description: props.document.id,
    icon: wasFav ? 'i-lucide-bookmark-x' : 'i-lucide-bookmark-check',
    color: wasFav ? 'neutral' : 'primary',
    duration: 1800
  })
}
</script>

<template>
  <UDashboardPanel id="entrelinea-detail">
    <UDashboardNavbar :title="document.origin||title" :toggle="false">
      <template #leading>
        <UButton
          icon="i-lucide-x"
          color="neutral"
          variant="ghost"
          class="-ms-1.5"
          @click="emits('close')"
        />
      </template>

      <template #right>
        <UTooltip :text="isFav ? 'Quitar de mi lista' : 'Guardar en mi lista'">
          <UButton
            :icon="isFav ? 'i-lucide-bookmark-check' : 'i-lucide-bookmark-plus'"
            :color="isFav ? 'primary' : 'neutral'"
            variant="ghost"
            :aria-label="isFav ? 'Quitar de mi lista' : 'Guardar en mi lista'"
            @click="onToggleFavorite"
          />
        </UTooltip>
      </template>
    </UDashboardNavbar>

    <div class="flex flex-col sm:flex-row justify-between gap-2 p-4 sm:px-6 border-b border-default">
      <div class="min-w-0 flex items-center gap-2 text-xs text-muted">
        <UBadge
          v-if="document.filter"
          :label="String(document.filter).toUpperCase()"
          color="neutral"
          variant="subtle"
          size="sm"
        />
        <UBadge
          v-if="document.type"
          :label="String(document.type).toUpperCase()"
          color="neutral"
          variant="subtle"
          size="sm"
        />

        <span v-if="document.page != null">Página {{ document.page }}</span>
      </div>
    </div>

    <div class="flex-1 overflow-y-auto relative bg-gray-100">
      <!--
        Padding extra a la derecha (pe-16/20) y al fondo (pb-24) para que el
        FAB sticky de favorito NUNCA se superponga al contenido: el contenedor
        reserva una "zona muerta" en la esquina inferior derecha donde el
        botón puede flotar sin tapar texto ni la imagen.
      -->
      <div class="p-1 sm:p-4 bg-white rounded-lg shadow-md max-w-4xl m-4 sm:mx-auto sm:my-6">
        <!-- Imagen desde ImageKit -->
        <div
          v-if="imageUrl"
          class="rounded-lg overflow-hidden border border-default bg-elevated flex items-center justify-center mb-2"
        >
          <img
            :src="imageUrl"
            :alt="title"
            loading="lazy"
            class="max-w-full h-auto"
          >
        </div>
        <div
          v-else
          class="rounded-lg border border-dashed border-default p-8 text-center text-xs text-dimmed"
        >
          <UIcon name="i-lucide-image-off" class="size-6 mb-1 mx-auto" />
          <p>Sin imagen disponible</p>
        </div>

        <!-- Entrelínea (text) — usa la versión resaltada si Typesense la
             devolvió, si no el HTML crudo del documento. -->
        <article
          v-if="bodyHtml"
          class="prose prose-sm max-w-none dark:prose-invert"
          v-html="bodyHtml"
        />
        <p v-else class="text-sm text-muted">
          No hay entrelínea para esta coincidencia.
        </p>
      </div>

      <!--
        FAB de favorito — mismo patrón que en InboxActivity: contenedor
        `sticky bottom-0 h-0` con `pointer-events-none` para que ocupe cero
        altura en el flujo y el botón quede anclado al borde inferior
        visible mientras el usuario hace scroll. El padding `pe-16/pb-24`
        del contenedor de contenido garantiza que NUNCA tape texto ni imagen.
      -->
      
    </div>
  </UDashboardPanel>
</template>
