<template>
    <div class="schema-typer">
      <span class="token-tag">&lt;<span class="token-tag-name">script</span> <span class="token-attr">type</span>=<span class="token-string">"application/ld+json"</span>&gt;</span><br >
      <span
        v-for="(line, lineIndex) in displayedLines"
        :key="lineIndex"
        class="code-line"
      >
        <template v-for="(segment, index) in line" :key="index">
          <span :class="segment.class">{{ segment.text }}</span>
        </template>
        <template v-if="(lineIndex === currentLine || (isTypingDone && lineIndex === displayedLines.length - 1)) && showCursor">
          <span class="cursor">|</span>
        </template>
        <br >
      </span>
      <span class="token-tag">&lt;/<span class="token-tag-name">script</span>&gt;</span>
    </div>
  </template>
  
  <script setup>
  import { ref, onMounted } from 'vue'
  
  const schema = `{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "So machen wir deine Website KI-kompatibel",
  "description": "Wir optimieren deine Website gezielt für künstliche Intelligenz. Strukturiert, effizient und zukunftssicher.",
  "step1": "Wir integrieren strukturierte Daten nach schema.org, damit KI-Systeme Inhalte korrekt interpretieren können.",
  "step2": "Wir überarbeiten den Quellcode mit semantischem HTML und klaren Überschriften zur besseren maschinellen Lesbarkeit.",
  "step3": "Wir stellen relevante Inhalte zusätzlich in maschinenfreundlichen Formaten wie JSON-LD oder über APIs bereit.",
  "step4": "Wir sorgen für barrierefreie Gestaltung und klare Sprache, so verstehen auch KI-Sprachmodelle deine Inhalte besser.",
  "step5": "Wir ergänzen deine Seiten mit Metadaten wie OpenGraph, Twitter Cards und Robots-Tags für optimalen Kontext.",
  "estimatedTime": "ca. 45 Minuten Analyse + Umsetzung je nach Umfang",
  "image": "/images/ki-optimierung.jpg"
  }`
  
  function parseLine(line) {
    const segments = []
    const regex = /("[^"]+":)|("[^"]+")|(\d+)|(true|false|null)|(\s+|[{}[\],:])/g
    let match
    let lastIndex = 0
  
    while ((match = regex.exec(line)) !== null) {
      const start = match.index
      if (start > lastIndex) {
        segments.push({ text: line.slice(lastIndex, start), class: 'token-text' })
      }
  
      const [matched, key, str, num, bool, symbol] = match
      let cls = 'token-text'
      if (key) cls = 'token-key'
      else if (str) cls = 'token-string'
      else if (num) cls = 'token-number'
      else if (bool) cls = 'token-boolean'
      else if (symbol) cls = 'token-text'
  
      segments.push({ text: matched, class: cls })
      lastIndex = start + matched.length
    }
  
    if (lastIndex < line.length) {
      segments.push({ text: line.slice(lastIndex), class: 'token-text' })
    }
  
    return segments
  }
  
  const lines = schema.split('\n').map(parseLine)
  const displayedLines = ref([])
  const showCursor = ref(true)
  const currentLine = ref(0)
  const isTypingDone = ref(false)
  
  const startTyping = () => {
    let lineIndex = 0
    let charIndex = 0
    displayedLines.value.push([])
  
    const typeChar = () => {
      if (lineIndex >= lines.length) {
        isTypingDone.value = true
        return
      }
  
      const segment = lines[lineIndex][charIndex]
      if (segment) {
        displayedLines.value[lineIndex].push(segment)
        charIndex++
      } else {
        lineIndex++
        charIndex = 0
        currentLine.value = lineIndex
        if (lineIndex < lines.length) displayedLines.value.push([])
      }
  
      setTimeout(typeChar, Math.random() * 80 + 40)
    }
  
    typeChar()
    setInterval(() => (showCursor.value = !showCursor.value), 500)
  }
  
  onMounted(() => {
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        observer.disconnect()
        startTyping()
      }
    }, { threshold: 0.3 })
  
    const el = document.querySelector('.schema-typer')
    if (el) observer.observe(el)
  })
  </script>
  
  
  <style lang="sass" scoped>
  .schema-typer
    background-color: #1e1e1e
    padding: 1.5rem
    margin: 2rem
    border-radius: 0.5rem
    font-family: monospace
    font-size: 0.7rem
    color: #ffffff
    overflow-x: auto
    overflow-y: auto
    line-height: 1.4
    height: auto
    min-height: 450px
    width: 400px
    transform: rotate(6deg)
    box-shadow: -3px 3px 6px 4px grey
  
  span
    margin: 0
    padding: 0
  
  .code-line
    display: block
    line-height: 1.2
  
  .token-tag
    color: #569cd6
  
  .token-tag-name
    color: #4ec9b0
  
  .token-attr
    color: #c586c0
  
  .token-key
    color: #9cdcfe
    margin-left: 1rem
  
  .token-string
    color: #ce9178
  
  .token-number
    color: #b5cea8
  
  .token-boolean
    color: #dcdcaa
  
  .token-text
    color: #d4d4d4
    margin-left: .2rem
  
  .cursor
    display: inline-block
    width: 1ch
    background-color: white
    animation: blink 1s steps(2, start) infinite
  
  @keyframes blink
    to
      visibility: hidden
  </style>
  