<script setup>
import { computed, ref, nextTick } from 'vue'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import { htmlUrl, chatGuide } from '../api.js'

marked.setOptions({ breaks: true, gfm: true })

function renderMarkdown(text) {
  return DOMPurify.sanitize(marked.parse(text || ''))
}

const props = defineProps({
  previewGuide: { type: Object, default: null },
})

const LANDSCAPE_FORMATS = ['OnePager', 'Cheatsheet']
const isLandscape = computed(() => LANDSCAPE_FORMATS.includes(props.previewGuide?.format))

const frameEl = ref(null)

function injectPadding(e) {
  if (isLandscape.value) return
  const doc = e.target.contentDocument
  if (!doc) return
  const style = doc.createElement('style')
  style.textContent = `@media screen {
    html { background: #f0f1f4; }
    body {
      zoom: 1.15;
      max-width: 1000px;
      margin: 0 auto;
      padding: 2.5rem 3.5rem;
      background: #fff;
      box-shadow: 0 1px 8px rgba(0, 0, 0, 0.08);
    }
  }`
  doc.head?.appendChild(style)
}

// --- Chat ---
const chatOpen = ref(false)
const messages = ref([])
const input = ref('')
const loading = ref(false)
const messagesEl = ref(null)
const inputEl = ref(null)

function openChat() {
  chatOpen.value = true
  nextTick(() => inputEl.value?.focus())
}

function closeChat() {
  chatOpen.value = false
  messages.value = []
  input.value = ''
}

function extractContext() {
  try {
    const doc = frameEl.value?.contentDocument
    if (!doc) return { section: '', outline: '' }
    const headings = Array.from(doc.querySelectorAll('h1, h2, h3'))
    if (!headings.length) return { section: '', outline: '' }

    const outline = headings.map((h) => h.innerText.trim()).filter(Boolean).join('\n')

    // Aktuelle Überschrift = letzte, die oben im sichtbaren Bereich oder darüber liegt
    let current = headings[0]
    for (const h of headings) {
      if (h.getBoundingClientRect().top <= 100) current = h
      else break
    }
    const level = Number(current.tagName[1])
    const idx = headings.indexOf(current)
    let end = null
    for (let i = idx + 1; i < headings.length; i++) {
      if (Number(headings[i].tagName[1]) <= level) { end = headings[i]; break }
    }
    const range = doc.createRange()
    range.setStartBefore(current)
    if (end) range.setEndBefore(end)
    else range.setEndAfter(doc.body.lastElementChild || doc.body)
    const section = range.toString().trim().slice(0, 18000)
    return { section, outline: outline.slice(0, 7000) }
  } catch {
    return { section: '', outline: '' }
  }
}

async function scrollToBottom() {
  await nextTick()
  if (messagesEl.value) messagesEl.value.scrollTop = messagesEl.value.scrollHeight
}

async function send() {
  const text = input.value.trim()
  if (!text || loading.value || !props.previewGuide) return
  messages.value.push({ role: 'user', content: text })
  input.value = ''
  loading.value = true
  scrollToBottom()
  try {
    const { section, outline } = extractContext()
    const res = await chatGuide(props.previewGuide.id, {
      section,
      outline,
      messages: messages.value,
    })
    messages.value.push({ role: 'assistant', content: res.reply || '…' })
  } catch {
    messages.value.push({ role: 'assistant', content: 'Fehler bei der Anfrage.' })
  } finally {
    loading.value = false
    scrollToBottom()
    nextTick(() => inputEl.value?.focus())
  }
}
</script>

<template>
  <div class="detail">
    <div class="preview" :class="{ landscape: isLandscape }" v-if="previewGuide">
      <iframe ref="frameEl" :src="htmlUrl(previewGuide.id)" class="preview-frame" :class="{ landscape: isLandscape }" title="Guide-Vorschau" @load="injectPadding"></iframe>
    </div>

    <div class="empty-preview" v-else>
      <p>Guide-Format anklicken um zu generieren oder Vorschau zu öffnen.</p>
    </div>

    <button v-if="previewGuide && !chatOpen" class="chat-fab" title="Fragen zum Guide" @click="openChat">💬</button>

    <div v-if="previewGuide && chatOpen" class="chat-panel">
      <header class="chat-header">
        <span>Fragen zum Guide</span>
        <button class="chat-close" title="Chat beenden" @click="closeChat">×</button>
      </header>
      <div ref="messagesEl" class="chat-messages">
        <p v-if="!messages.length" class="chat-hint">Stell eine Frage zum aktuellen Abschnitt.</p>
        <template v-for="(m, i) in messages" :key="i">
          <div v-if="m.role === 'assistant'" class="chat-msg assistant markdown" v-html="renderMarkdown(m.content)"></div>
          <div v-else class="chat-msg user">{{ m.content }}</div>
        </template>
        <div v-if="loading" class="chat-msg assistant chat-typing">Denkt…</div>
      </div>
      <div class="chat-input">
        <textarea
          ref="inputEl"
          v-model="input"
          placeholder="Frage stellen…"
          @keydown.enter.exact.prevent="send"
        ></textarea>
        <button :disabled="!input.trim() || loading" @click="send">➤</button>
      </div>
    </div>
  </div>
</template>

<style scoped>
.detail {
  flex: 1;
  height: 100vh;
}

.preview {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: #f0f1f4;
}

.preview.landscape {
  padding: 2rem;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.4rem 1rem;
  background: #f8f9fb;
  border-bottom: 1px solid #e2e5e9;
  font-size: 0.85rem;
  font-weight: 600;
  color: #5a6470;
  flex-shrink: 0;
}

.preview-actions {
  display: flex;
  gap: 0.75rem;
}

.preview-link {
  color: #6366f1;
  text-decoration: none;
  font-size: 0.8rem;
}

.preview-link:hover {
  text-decoration: underline;
}

.preview-frame {
  width: 100%;
  flex: 1;
  border: none;
  background: #fff;
}

.preview-frame.landscape {
  max-width: 1180px;
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.08);
}

.empty-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #5a6470;
}

.chat-fab {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  width: 52px;
  height: 52px;
  border: none;
  border-radius: 50%;
  background: #6366f1;
  color: #fff;
  font-size: 1.4rem;
  cursor: pointer;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
  z-index: 20;
}

.chat-fab:hover {
  background: #4f46e5;
}

.chat-panel {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  width: 360px;
  height: 500px;
  max-height: calc(100vh - 3rem);
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid #e2e5e9;
  border-radius: 12px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.18);
  z-index: 20;
  overflow: hidden;
}

.chat-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 0.9rem;
  background: #6366f1;
  color: #fff;
  font-weight: 600;
  font-size: 0.9rem;
}

.chat-close {
  border: none;
  background: none;
  color: #fff;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.chat-hint {
  color: #9aa3af;
  font-size: 0.82rem;
  text-align: center;
  margin-top: 1rem;
}

.chat-msg {
  max-width: 85%;
  padding: 7px 11px;
  border-radius: 12px;
  font-size: 0.85rem;
  line-height: 1.4;
  white-space: pre-wrap;
  word-break: break-word;
}

.chat-msg.user {
  align-self: flex-end;
  background: #6366f1;
  color: #fff;
  border-bottom-right-radius: 3px;
}

.chat-msg.assistant {
  align-self: flex-start;
  background: #f1f3f7;
  color: #1a1a1a;
  border-bottom-left-radius: 3px;
}

.chat-typing {
  color: #9aa3af;
  font-style: italic;
}

.chat-msg.markdown :deep(p) {
  margin: 0 0 0.5em;
}

.chat-msg.markdown :deep(p:last-child) {
  margin-bottom: 0;
}

.chat-msg.markdown :deep(ul),
.chat-msg.markdown :deep(ol) {
  margin: 0.3em 0;
  padding-left: 1.2em;
}

.chat-msg.markdown :deep(li) {
  margin: 0.15em 0;
}

.chat-msg.markdown :deep(code) {
  background: #e4e7ee;
  padding: 1px 4px;
  border-radius: 4px;
  font-family: "SF Mono", Consolas, monospace;
  font-size: 0.8em;
}

.chat-msg.markdown :deep(pre) {
  background: #1e2330;
  color: #e6e8ee;
  padding: 8px 10px;
  border-radius: 8px;
  overflow-x: auto;
  margin: 0.5em 0;
}

.chat-msg.markdown :deep(pre code) {
  background: none;
  padding: 0;
  color: inherit;
  font-size: 0.78em;
}

.chat-msg.markdown :deep(h1),
.chat-msg.markdown :deep(h2),
.chat-msg.markdown :deep(h3) {
  font-size: 0.95em;
  margin: 0.4em 0 0.2em;
}

.chat-msg.markdown :deep(a) {
  color: #4f46e5;
}

.chat-msg.markdown :deep(table) {
  border-collapse: collapse;
  font-size: 0.95em;
}

.chat-msg.markdown :deep(th),
.chat-msg.markdown :deep(td) {
  border: 1px solid #d8dde3;
  padding: 2px 6px;
}

.chat-input {
  display: flex;
  gap: 6px;
  padding: 0.6rem;
  border-top: 1px solid #e2e5e9;
}

.chat-input textarea {
  flex: 1;
  resize: none;
  height: 38px;
  padding: 8px 10px;
  border: 1px solid #d8dde3;
  border-radius: 8px;
  font-size: 0.85rem;
  font-family: inherit;
  outline: none;
}

.chat-input textarea:focus {
  border-color: #6366f1;
}

.chat-input button {
  width: 38px;
  border: none;
  border-radius: 8px;
  background: #6366f1;
  color: #fff;
  font-size: 1rem;
  cursor: pointer;
}

.chat-input button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
</style>
