<script setup>
import { ref, watch } from 'vue'
import { updateElement, checkElement, styleElement, refineSuggestion } from '../../api.js'
import { renderMarkdown } from '../../markdown.js'
import ElementSuggestion from './ElementSuggestion.vue'
import ElementChatTab from './ElementChatTab.vue'
import ElementEditTab from './ElementEditTab.vue'

const props = defineProps({
  element: { type: Object, required: true },
  provider: { type: String, default: 'claude' },
})

const emit = defineEmits(['back', 'close', 'updated', 'changed'])

const tab = ref('overview') // 'overview' | 'chat' | 'edit'
const savingEdit = ref(false)

// Markdown-Zeichen aus dem Header-Titel entfernen
function plain(text) {
  return (text || '').replace(/```[a-z]*\n?/g, '').replace(/[`*_#]/g, '')
}

// Anderes Element gewählt → Prüf-Zustand und Tab zurücksetzen
watch(() => props.element.id, () => {
  tab.value = 'overview'
  resetCheck()
})

// --- KI-Prüfung auf fehlende Infos (Ergebnisse landen als Inline-Vorschläge) ---
const checking = ref(false)
const statusMsg = ref(null)

function resetCheck() {
  checking.value = false
  statusMsg.value = null
  resetStyle()
}

let checkRun = 0 // laufende Prüfung identifizieren; Abbruch ignoriert ihr Ergebnis

async function runCheck() {
  if (checking.value) { // zweiter Klick = abbrechen
    checkRun++
    checking.value = false
    return
  }
  const run = ++checkRun
  checking.value = true
  statusMsg.value = null
  try {
    const res = await checkElement(props.element.id, props.provider)
    if (run !== checkRun) return // abgebrochen oder neue Prüfung gestartet
    const mapped = res.suggestions.map((s) => ({
      text: s.text, action: 'hinzufuegen', target: s.target, index: null, content: s.content,
    }))
    if (mapped.length) styleChanges.value = [...(styleChanges.value || []), ...mapped]
    else statusMsg.value = 'Keine wichtigen Lücken gefunden.'
  } catch (e) {
    if (run !== checkRun) return
    console.error('Prüfung fehlgeschlagen:', e)
    statusMsg.value = 'Prüfung fehlgeschlagen — bitte erneut versuchen.'
  } finally {
    if (run === checkRun) checking.value = false
  }
}

// --- Stil-Prüfung: KI schlägt Änderungen vor, Nutzer bestätigt ---
const styleChanges = ref(null) // null = noch nicht geprüft
const styling = ref(false)
const applyingStyle = ref(false)
const refiningIdx = ref(null)
let styleRun = 0

function resetStyle() {
  styleChanges.value = null
  styling.value = false
  applyingStyle.value = false
  refiningIdx.value = null
}

function suggBusy(i) {
  return applyingStyle.value || refiningIdx.value === i
}

// Einzelnen Vorschlag per Anweisung überarbeiten (Stift-Icon)
async function refineChange(i, instruction) {
  if (refiningIdx.value !== null || applyingStyle.value) return
  refiningIdx.value = i
  try {
    const res = await refineSuggestion(props.element.id, styleChanges.value[i], instruction, props.provider)
    const next = [...styleChanges.value]
    next[i] = res.change
    styleChanges.value = next
  } catch (e) {
    console.error('Überarbeitung fehlgeschlagen:', e)
    statusMsg.value = 'Überarbeitung fehlgeschlagen — bitte erneut versuchen.'
  } finally {
    refiningIdx.value = null
  }
}

async function runStyle() {
  if (styling.value) { // zweiter Klick = abbrechen
    styleRun++
    styling.value = false
    return
  }
  const run = ++styleRun
  styling.value = true
  statusMsg.value = null
  try {
    const res = await styleElement(props.element.id, props.provider)
    if (run !== styleRun) return
    if (res.changes.length) styleChanges.value = [...(styleChanges.value || []), ...res.changes]
    else statusMsg.value = 'Stil passt bereits.'
  } catch (e) {
    if (run !== styleRun) return
    console.error('Stil-Prüfung fehlgeschlagen:', e)
    statusMsg.value = 'Stil-Prüfung fehlgeschlagen — bitte erneut versuchen.'
  } finally {
    if (run === styleRun) styling.value = false
  }
}

// Chat-Vorschläge landen ebenfalls als Inline-Vorschläge in der Übersicht
function onChatChanges(changes) {
  styleChanges.value = [...(styleChanges.value || []), ...changes]
}

// Vorschläge am Ziel-Ort anzeigen: anpassen/entfernen beim betroffenen Eintrag …
function styleAt(target, index = null) {
  if (!styleChanges.value) return []
  return styleChanges.value
    .map((c, i) => [i, c])
    .filter(([, c]) => c.target === target && c.index === index && c.action !== 'hinzufuegen')
}

// … Ergänzungen am Ende der jeweiligen Sektion
function styleAdds(target) {
  if (!styleChanges.value) return []
  return styleChanges.value
    .map((c, i) => [i, c])
    .filter(([, c]) => c.target === target && c.action === 'hinzufuegen')
}

function dismissStyleChange(i) {
  styleChanges.value = styleChanges.value.filter((_, j) => j !== i)
}

async function applyStyleChange(i) {
  if (applyingStyle.value) return
  const c = styleChanges.value[i]
  applyingStyle.value = true
  try {
    const STRING_TARGETS = ['title', 'description']
    const fields = {
      title: props.element.title,
      description: props.element.description,
      examples: [...props.element.examples],
      hints: [...props.element.hints],
    }
    if (c.action === 'entfernen') fields[c.target].splice(c.index, 1)
    else if (c.action === 'hinzufuegen') {
      if (c.target === 'title') fields.title = c.content
      else if (c.target === 'description')
        fields[c.target] = fields[c.target] ? fields[c.target] + '\n\n' + c.content : c.content
      else fields[c.target].push(c.content)
    } else if (STRING_TARGETS.includes(c.target)) fields[c.target] = c.content
    else fields[c.target][c.index] = c.content

    const updated = await updateElement(props.element.id, fields)
    emit('updated', updated)

    // Rest-Vorschläge behalten; Indizes hinter einer Entfernung rücken auf
    const rest = styleChanges.value.filter((_, j) => j !== i)
    if (c.action === 'entfernen') {
      for (const r of rest) {
        if (r.target === c.target && r.index !== null && r.index > c.index) r.index--
      }
    }
    styleChanges.value = rest
  } catch (e) {
    console.error('Übernehmen fehlgeschlagen:', e)
  } finally {
    applyingStyle.value = false
  }
}

// --- Bearbeiten-Tab: Felder direkt speichern ---
async function saveEdit(fields) {
  if (savingEdit.value) return
  savingEdit.value = true
  try {
    const updated = await updateElement(props.element.id, fields)
    emit('updated', updated)
    tab.value = 'overview'
  } catch (e) {
    console.error('Speichern fehlgeschlagen:', e)
  } finally {
    savingEdit.value = false
  }
}
</script>

<template>
  <header class="el-header">
    <button class="el-back" title="Zur Liste" @click="emit('back')">←</button>
    <span class="el-title">{{ plain(element.title) }}</span>
    <button
      class="el-tool" :class="{ busy: checking }"
      :title="checking ? 'Prüfung abbrechen' : 'Auf fehlende Infos prüfen'" @click="runCheck"
    >🔍</button>
    <button
      class="el-tool" :class="{ busy: styling }"
      :title="styling ? 'Prüfung abbrechen' : 'Stil prüfen & anpassen'" @click="runStyle"
    >✨</button>
    <button class="el-close" title="Schließen" @click="emit('close')">×</button>
  </header>

  <nav class="el-tabs">
    <button :class="{ active: tab === 'overview' }" @click="tab = 'overview'">Übersicht</button>
    <button :class="{ active: tab === 'chat' }" @click="tab = 'chat'">Chat</button>
    <button :class="{ active: tab === 'edit' }" @click="tab = 'edit'">Bearbeiten</button>
  </nav>

  <!-- Übersicht: untrennbar mit styleChanges/Apply verzahnt → bleibt hier -->
  <div v-show="tab === 'overview'" class="el-detail">
    <div v-if="element.description" class="el-desc markdown" v-html="renderMarkdown(element.description)"></div>
    <ElementSuggestion
      v-for="[ci, c] in [...styleAt('title'), ...styleAt('description'), ...styleAdds('description')]"
      :key="'sgd' + ci" :change="c" :busy="suggBusy(ci)"
      @apply="applyStyleChange(ci)" @dismiss="dismissStyleChange(ci)" @refine="(t) => refineChange(ci, t)"
    />
    <template v-for="(ex, i) in element.examples" :key="i">
      <div class="el-entry markdown" v-html="renderMarkdown(ex)"></div>
      <ElementSuggestion
        v-for="[ci, c] in styleAt('examples', i)"
        :key="'sge' + ci" :change="c" :busy="suggBusy(ci)"
        @apply="applyStyleChange(ci)" @dismiss="dismissStyleChange(ci)" @refine="(t) => refineChange(ci, t)"
      />
    </template>
    <ElementSuggestion
      v-for="[ci, c] in styleAdds('examples')"
      :key="'sgea' + ci" :change="c" :busy="suggBusy(ci)"
      @apply="applyStyleChange(ci)" @dismiss="dismissStyleChange(ci)" @refine="(t) => refineChange(ci, t)"
    />
    <div v-if="element.hints.length || styleAdds('hints').length" class="el-hints-block">
      <h4>Hinweise</h4>
      <ul class="el-hints">
        <li v-for="(h, i) in element.hints" :key="i">
          <span class="markdown" v-html="renderMarkdown(h)"></span>
          <ElementSuggestion
            v-for="[ci, c] in styleAt('hints', i)"
            :key="'sgh' + ci" :change="c" :busy="suggBusy(ci)"
            @apply="applyStyleChange(ci)" @dismiss="dismissStyleChange(ci)" @refine="(t) => refineChange(ci, t)"
          />
        </li>
      </ul>
      <ElementSuggestion
        v-for="[ci, c] in styleAdds('hints')"
        :key="'sgha' + ci" :change="c" :busy="suggBusy(ci)"
        @apply="applyStyleChange(ci)" @dismiss="dismissStyleChange(ci)" @refine="(t) => refineChange(ci, t)"
      />
    </div>

    <div v-if="checking || styling || statusMsg" class="el-check">
      <p v-if="checking" class="check-empty busy-text">Prüft auf fehlende Infos…</p>
      <p v-if="styling" class="check-empty busy-text">Prüft den Stil…</p>
      <p v-if="statusMsg && !checking && !styling" class="check-empty">{{ statusMsg }}</p>
    </div>
  </div>

  <!-- v-show erhält den Chat-Verlauf beim Tab-Wechsel -->
  <ElementChatTab
    v-show="tab === 'chat'"
    :element="element"
    :provider="provider"
    @changes="onChatChanges"
  />

  <!-- v-if lädt die Edit-Felder bei jedem Öffnen frisch -->
  <ElementEditTab
    v-if="tab === 'edit'"
    :element="element"
    :saving="savingEdit"
    @save="saveEdit"
  />
</template>

<style scoped>
.el-header {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--border);
}

.el-title {
  flex: 1;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.el-back,
.el-close {
  border: none;
  background: none;
  color: var(--text-faint);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.el-back:hover,
.el-close:hover {
  color: var(--text);
}

.el-tool {
  border: none;
  background: none;
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  padding: 2px 3px;
  border-radius: 6px;
  filter: grayscale(0.4);
}

.el-tool:hover {
  background: var(--panel-soft);
  filter: none;
}

.el-tool.busy {
  filter: none;
  animation: pulse 1.5s ease-in-out infinite;
}

.busy-text {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  50% { opacity: 0.35; }
}

.el-tabs {
  display: flex;
  border-bottom: 1px solid var(--border);
}

.el-tabs button {
  flex: 1;
  padding: 0.5rem 0.25rem;
  border: none;
  background: none;
  color: var(--text-muted);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  border-bottom: 2px solid transparent;
}

.el-tabs button.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.el-tabs button:hover:not(.active) {
  color: var(--text);
}

.el-detail {
  flex: 1;
  overflow-y: auto;
  padding: 0.9rem;
}

.el-desc {
  margin: 0 0 0.9rem;
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--text);
}

.el-hints-block {
  margin-top: 0.9rem;
}

.el-hints-block h4 {
  margin: 0 0 0.35rem;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
}

.el-entry {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text);
  margin-bottom: 0.4rem;
}

.el-entry:last-child {
  margin-bottom: 0;
}

.el-hints {
  margin: 0;
  padding-left: 1.1rem;
}

.el-hints li {
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text);
  margin-bottom: 0.25rem;
}

/* Hinweis-Text inline neben dem Bullet halten (p ist sonst block) */
.el-hints li > .markdown {
  display: inline;
}

.el-hints li > .markdown :deep(p) {
  display: inline;
  margin: 0;
}

/* Markdown: Basis global (assets/markdown.css); schmale Sidebar → kompaktere Code-Blöcke */
.markdown :deep(pre) {
  padding: 8px 10px;
}

/* --- KI-Prüfung --- */
.el-check {
  margin-top: 1rem;
  padding-top: 0.8rem;
  border-top: 1px dashed var(--border-strong);
}

.check-empty {
  margin: 0.6rem 0 0;
  font-size: 0.78rem;
  color: var(--text-faint);
  text-align: center;
}
</style>
