// Parser für Lyras LLM-JSON-Antworten + Emotion-Detection.
import { EMPATHY_RE, HAPPY_RE } from './sosConstants';
import type { Emotion } from '../components/RiveAvatar';

export type LyraEmotion = Emotion;
export type ChipSpec = { label: string; action: string };

// Parse LLM JSON response — robust gegen Markdown-Fences UND abgeschnittenes JSON
export function parseLyraResponse(raw: string): { message: string; chips: ChipSpec[] } {
  if (!raw) return { message: '', chips: [] };
  // Strip ALL markdown fences (auch wenn nur am Anfang)
  const text = raw.trim()
    .replace(/^```(?:json)?\s*/i, '')
    .replace(/```\s*$/i, '')
    .trim();
  const start = text.indexOf('{');
  if (start === -1) return { message: raw.trim(), chips: [] };
  // Erst echtes JSON-Parse versuchen (komplett)
  const end = text.lastIndexOf('}');
  if (end > start) {
    try {
      const obj = JSON.parse(text.slice(start, end + 1));
      const message = typeof obj.message === 'string' ? obj.message.trim() : '';
      const chipsRaw = Array.isArray(obj.chips) ? obj.chips : [];
      const chips: ChipSpec[] = chipsRaw
        .filter((c: { label?: unknown; action?: unknown }) => c && typeof c.label === 'string' && typeof c.action === 'string')
        .slice(0, 5)
        .map((c: { label: string; action: string }) => ({ label: c.label.trim(), action: c.action.trim() }));
      if (message) return { message, chips };
    } catch {/* fall through to recovery */}
  }
  // RECOVERY: JSON ist abgeschnitten (z.B. max_tokens hit).
  // 1) message-Feld per Regex extrahieren
  const msgMatch = text.match(/"message"\s*:\s*"((?:[^"\\]|\\.)*)"/);
  let message = '';
  if (msgMatch) {
    try { message = JSON.parse('"' + msgMatch[1] + '"'); } catch { message = msgMatch[1]; }
  }
  // 2) Chips: alle vollständigen {label,action}-Objekte einsammeln
  const chips: ChipSpec[] = [];
  const chipRe = /\{\s*"label"\s*:\s*"((?:[^"\\]|\\.)*)"\s*,\s*"action"\s*:\s*"((?:[^"\\]|\\.)*)"\s*\}/g;
  let m: RegExpExecArray | null;
  while ((m = chipRe.exec(text)) !== null && chips.length < 5) {
    try {
      chips.push({
        label: JSON.parse('"' + m[1] + '"').trim(),
        action: JSON.parse('"' + m[2] + '"').trim(),
      });
    } catch {
      chips.push({ label: m[1].trim(), action: m[2].trim() });
    }
  }
  if (message) return { message, chips };
  return { message: raw.trim(), chips: [] };
}

export function detectEmotion(text: string): LyraEmotion {
  if (HAPPY_RE.test(text)) return 'happy';
  if (EMPATHY_RE.test(text)) return 'empathy';
  return 'idle';
}
