<script setup lang="ts">
/**
 * PageView — the page editing surface for any non-journal `.md` file.
 *
 * Two distinct zones:
 * 1. **Writing surface** (top): editable title `<input>` styled as `<h1>`,
 *    breadcrumb path, and the Editor with bubble toolbar. Renaming the title
 *    emits `rename` — the parent handles the actual file rename on disk.
 * 2. **Backlinks panel** (bottom): collapsible list of cards showing where
 *    `[[This Page]]` is referenced from, with highlighted excerpts for context.
 *
 * Content is two-way bound via `:content` / `@update:content`, so the parent
 * can debounce auto-save without this component knowing about the filesystem.
 *
 * Navigation (`@page-ref-clicked`, `@block-ref-clicked`, `@tag-clicked`)
 * is handled internally via `usePageNavigation` — events don't bubble up.
 *
 * @remarks Edge cases & deferred work:
 * - The `formatExcerpt` function uses `String.slice()` for excerpt extraction,
 *   which operates on UTF-16 code units. This is safe for BMP characters but
 *   may split in the middle of a 4-byte Unicode character (e.g. emoji) if the
 *   link offset falls inside one. A code-point-aware iteration would fix this.
 * - Renaming the title emits `rename` to the parent, but does NOT update
 *   `[[links]]` in other files that reference the old name. The parent handles
 *   the filesystem rename; updating cross-file references is deferred.
 * - The backlinks panel shows up to 50 results. No pagination is implemented.
 */
import { Editor, EditorToolbar } from "@enesis/editor"
import { useVModel } from "@vueuse/core"
import { ref, watch } from "vue"
import { useIndexSuggestions } from "~/composables/useIndexSuggestions"
import { usePageNavigation } from "~/composables/usePageNavigation"
import { escapeHtml } from "~/lib/parse"

export interface Backlink {
  sourceType: "journal" | "page"
  sourceName: string
  sourcePath: string
  excerpt: string
}

const props = defineProps<{
  path: string
  filename: string
  content: string
  backlinks: Backlink[]
  targetBlockId?: string | null
}>()

const emit = defineEmits<{
  "update:content": [value: string]
  rename: [newName: string]
  "backlink-clicked": [sourcePath: string]
}>()

const { navigateToPage, navigateToBlock, navigateToTag } = usePageNavigation()
const { data: mentionData } = useIndexSuggestions()

const title = ref(props.filename.replace(/\.md$/, ""))
const backlinksOpen = ref(true)

const localContent = useVModel(props, "content", emit)

watch(
  () => props.filename,
  (name) => {
    title.value = name.replace(/\.md$/, "")
  },
)

function handleTitleBlur() {
  const trimmed = title.value.trim()
  if (!trimmed || trimmed === props.filename.replace(/\.md$/, "")) {
    title.value = props.filename.replace(/\.md$/, "")
    return
  }
  emit("rename", trimmed)
}

function handleTitleKeydown(e: KeyboardEvent) {
  if (e.key === "Enter") {
    e.preventDefault()
    ;(e.target as HTMLInputElement).blur()
  }
  if (e.key === "Escape") {
    title.value = props.filename.replace(/\.md$/, "")
    ;(e.target as HTMLInputElement).blur()
  }
}

function formatExcerpt(excerpt: string): string {
  const safe = escapeHtml(excerpt)
  return safe.replace(
    /\[\[([^\]]+)\]\]/g,
    '<mark class="bg-(--ui-primary)/15 text-(--ui-primary) rounded px-0.5 not-italic">$1</mark>',
  )
}
</script>

<template>
  <div class="flex flex-col min-h-full">

    <!-- Writing surface -->
    <div class="flex-1 w-full max-w-3xl mx-auto px-8 pt-16 pb-12">

      <!-- Path breadcrumb (relative to workspace root) -->
      <p class="text-xs text-muted/50 font-mono mb-6 select-none truncate">
        {{ path }}
      </p>

      <!-- Editable title -->
      <input
        v-model="title"
        type="text"
        class="w-full bg-transparent border-none outline-none
               text-4xl font-semibold text-highlighted tracking-tight
               placeholder:text-muted/30 mb-8"
        placeholder="Untitled"
        spellcheck="false"
        @blur="handleTitleBlur"
        @keydown="handleTitleKeydown"
      />

      <!-- Editor -->
      <Editor
        v-model:content="localContent"
        :mention-data="mentionData"
        marker-mode="live-preview"
        :focused="targetBlockId ? { kind: 'block', id: targetBlockId } : 'first-zone'"
        @page-ref-clicked="({ pageName, alias }) => navigateToPage(pageName)"
        @block-ref-clicked="({ blockId }) => navigateToBlock(blockId)"
        @tag-clicked="({ tag }) => navigateToTag(tag)"
      >
        <template #toolbar="{ handlers, selectionVersion, canUndo, canRedo, undo, redo }">
          <EditorToolbar
            mode="bubble"
            :handlers="handlers"
            :selection-version="selectionVersion"
            :can-undo="canUndo"
            :can-redo="canRedo"
            :undo="undo"
            :redo="redo"
          />
        </template>
      </Editor>

    </div>

    <!-- Backlinks -->
    <div
      v-if="backlinks.length > 0"
      class="w-full max-w-3xl mx-auto px-8 pb-16"
    >
      <USeparator class="mb-6" />

      <UCollapsible v-model:open="backlinksOpen">

        <button
          class="flex items-center gap-2 mb-4 group"

        >
          <UIcon
            name="i-lucide-arrow-left"
            class="w-3.5 h-3.5 text-muted/60"
          />
          <span class="text-xs font-medium text-muted uppercase tracking-widest">
            Linked references
          </span>
          <span class="text-xs text-muted/40 tabular-nums">
            {{ backlinks.length }}
          </span>
          <UIcon
            name="i-lucide-chevron-right"
            class="w-3 h-3 text-muted/40 transition-transform duration-150 ml-1"
            :class="{ 'rotate-90': backlinksOpen }"
          />
        </button>

        <template #content>
          <ul class="space-y-3">
            <li
              v-for="link in backlinks"
              :key="link.sourcePath"
            >
              <button
                class="group w-full text-left rounded-lg border border-default
                       hover:border-(--ui-primary)/30 hover:bg-elevated
                       px-4 py-3 transition-all duration-150
                       focus-visible:outline-none focus-visible:ring-2
                       focus-visible:ring-(--ui-primary)"
                @click="emit('backlink-clicked', link.sourcePath)"
              >
                <div class="flex items-center gap-1.5 mb-1.5">
                  <UIcon
                    :name="link.sourceType === 'journal'
                      ? 'i-lucide-calendar'
                      : 'i-lucide-file-text'"
                    class="w-3 h-3 text-muted/50 shrink-0"
                  />
                  <span class="text-xs font-medium text-muted group-hover:text-default transition-colors">
                    {{ link.sourceName }}
                  </span>
                </div>

                <p
                  class="text-sm text-muted/70 leading-relaxed line-clamp-2"
                  v-html="formatExcerpt(link.excerpt)"
                />
              </button>
            </li>
          </ul>
        </template>

      </UCollapsible>
    </div>

  </div>
</template>
