import { ref, nextTick } from 'vue'

// (Fast) am unteren Rand? Schwelle fängt Sub-Pixel und kleine Abstände ab.
export function istUnten(el, schwelle = 60) {
  return el.scrollHeight - el.scrollTop - el.clientHeight < schwelle
}

// Gemeinsame Chat-Mechanik: senden, abbrechen (Run-Counter), scrollen, Fokus.
// performRequest(messages) → Promise<{ reply, … }>; send() gibt die Antwort
// zurück, damit der Aufrufer Extras (z. B. changes) auswerten kann.
export function useChat(performRequest) {
  const messages = ref([])
  const input = ref('')
  const loading = ref(false)
  const messagesEl = ref(null) // Template-Ref: Nachrichten-Container
  const inputEl = ref(null)    // Template-Ref: Textarea
  const stick = ref(true)      // an den Boden „gepinnt" — nur dann auto-scrollen
  let run = 0 // laufende Anfrage identifizieren; Abbruch ignoriert ihr Ergebnis

  // @scroll-Handler: pinnt nur, wenn der Nutzer (fast) unten ist.
  function onScroll() {
    if (messagesEl.value) stick.value = istUnten(messagesEl.value)
  }

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

  function autoGrow(max = 140) {
    const el = inputEl.value
    if (!el) return
    el.style.height = 'auto'
    el.style.height = Math.min(el.scrollHeight, max) + 'px'
  }

  function cancel() {
    run++
    loading.value = false
    messages.value.push({ role: 'assistant', content: 'Abgebrochen.' })
  }

  function reset() {
    run++
    loading.value = false
    messages.value = []
    input.value = ''
  }

  async function send() {
    if (loading.value) { // zweiter Klick = abbrechen
      cancel()
      return null
    }
    const text = input.value.trim()
    if (!text) return null
    stick.value = true // eigenes Senden = ans Ende; Hochscrollen während des Wartens setzt es wieder false
    const current = ++run
    messages.value.push({ role: 'user', content: text })
    input.value = ''
    nextTick(() => autoGrow())
    loading.value = true
    scrollToBottom()
    try {
      const res = await performRequest(messages.value)
      if (current !== run) return null
      // Prüfung liefert `frage` (+ getrenntes `feedback`); andere Chats `reply`.
      messages.value.push({
        role: 'assistant',
        content: res.frage ?? res.reply ?? '…',
        feedback: res.feedback ?? null,
        bewertung: res.bewertung ?? null,
      })
      return res
    } catch {
      if (current !== run) return null
      messages.value.push({ role: 'assistant', content: 'Fehler bei der Anfrage.' })
      return null
    } finally {
      if (current === run) {
        loading.value = false
        scrollToBottom()
        nextTick(() => inputEl.value?.focus())
      }
    }
  }

  return { messages, input, loading, messagesEl, inputEl, stick, onScroll, send, cancel, reset, scrollToBottom, autoGrow }
}
