/**
 * ChiliColectivo Mic – Voice-Diktat für torchwood.app (Agenten-Modus).
 */
(function () {
  globalThis.__CHILLICOLLECTIVO_MIC = true;
  globalThis.__CHILLICOLLECTIVO_AGENTEN_MIC = true;
  globalThis.CHILLICOLLECTIVO_AGENT_SPEECH_LANG = 'de-CH';

  globalThis.chillicollectivoGetAgentSpeechLang = function chillicollectivoGetAgentSpeechLang() {
    return 'de-CH';
  };

  globalThis.chillicollectivoProcessSpeechText = function chillicollectivoProcessSpeechText(text) {
    const raw = String(text || '');
    if (!raw) return '';
    let t = raw;
    if (typeof chillicollectivoApplyVoiceTextRules === 'function') {
      t = chillicollectivoApplyVoiceTextRules(t, typeof chillicollectivoGetVoiceTextRules === 'function'
        ? chillicollectivoGetVoiceTextRules()
        : {});
    } else {
      t = t.replace(/ß/g, 'ss');
    }

    if (typeof chillicollectivoApplySpokenPunctuation === 'function') {
      t = chillicollectivoApplySpokenPunctuation(t);
    }

    if (t !== raw && globalThis.ChillicollectivoDiagnosticLog?.info) {
      const rawFlat = String(raw || '').replace(/\s+/g, ' ').trim();
      const correctedFlat = String(t || '').replace(/\s+/g, ' ').trim();
      const stripPunct = (value) => String(value || '')
        .replace(/[,.!?…:;"'\-]/g, '')
        .replace(/\s+/g, ' ')
        .trim()
        .toLowerCase();
      const punctuationOnly = stripPunct(rawFlat) === stripPunct(correctedFlat);
      const now = Date.now();
      const lastKey = globalThis.__chillicollectivoLastSpeechCorrectedKey || '';
      const lastAt = globalThis.__chillicollectivoLastSpeechCorrectedAt || 0;
      const key = `${rawFlat}→${correctedFlat}`;
      const isDuplicateLog = key === lastKey && now - lastAt < 1800;
      if (!isDuplicateLog) {
        globalThis.__chillicollectivoLastSpeechCorrectedKey = key;
        globalThis.__chillicollectivoLastSpeechCorrectedAt = now;
        const event = punctuationOnly ? 'voice.speech-punct-corrected' : 'voice.speech-corrected';
        const message = punctuationOnly ? 'STT-Satzzeichen umgewandelt' : 'STT-Korrektur (inhaltlich)';
        globalThis.ChillicollectivoDiagnosticLog.info(event, message, {
          raw: raw.slice(0, 300),
          corrected: t.slice(0, 300),
          rawSnippet: raw.slice(0, 160),
          correctedSnippet: t.slice(0, 160),
          correctionKind: punctuationOnly ? 'punctuation' : 'substantive',
        }).catch?.(() => {});
      }
    }
    return t;
  };

  globalThis.chillicollectivoNormalizeAgentSpeechText = function chillicollectivoNormalizeAgentSpeechText(text) {
    return chillicollectivoProcessSpeechText(text);
  };

  function syncVoiceTextRulesFromStorage() {
    if (!chrome?.storage?.local || typeof chillicollectivoRefreshVoiceTextRulesFromSettings !== 'function') return;
    chrome.storage.local.get(['chillicollectivoVoiceSettings'], (data) => {
      chillicollectivoRefreshVoiceTextRulesFromSettings(data?.chillicollectivoVoiceSettings || {});
    });
  }

  syncVoiceTextRulesFromStorage();
  if (chrome?.storage?.onChanged) {
    chrome.storage.onChanged.addListener((changes, area) => {
      if (area !== 'local' || !changes.chillicollectivoVoiceSettings) return;
      chillicollectivoRefreshVoiceTextRulesFromSettings(changes.chillicollectivoVoiceSettings.newValue || {});
    });
  }

  function isVisible(el) {
    if (!el || !el.getBoundingClientRect) return false;
    const r = el.getBoundingClientRect();
    if (r.width < 8 || r.height < 8) return false;
    const st = window.getComputedStyle(el);
    return st.display !== 'none' && st.visibility !== 'hidden' && Number(st.opacity) !== 0;
  }

  function findChatColumnRoot() {
    const vw = window.innerWidth || 1;
    const candidates = [
      ...document.querySelectorAll('[class*="Conversation"]'),
      ...document.querySelectorAll('[class*="Chat"]'),
      ...document.querySelectorAll('[class*="MessageInput"]'),
    ];
    let best = null;
    let bestScore = -1;
    candidates.forEach((el) => {
      if (!isVisible(el)) return;
      const r = el.getBoundingClientRect();
      const cx = r.left + r.width / 2;
      const centerDist = Math.abs(cx - vw / 2);
      const score = r.width * r.height - centerDist * 2;
      if (score > bestScore) {
        bestScore = score;
        best = el;
      }
    });
    return best;
  }

  function getFieldCharLength(field) {
    if (!field) return 0;
    if (field.isContentEditable) return String(field.textContent || '').length;
    return String(field.value ?? '').length;
  }

  function findComposeCharCounterNear(field) {
    if (!field) return null;
    const roots = [];
    let node = field;
    for (let i = 0; i < 8 && node; i++) {
      roots.push(node);
      node = node.parentElement;
    }
    for (const root of roots) {
      let matches = [];
      try {
        matches = [
          ...root.querySelectorAll('[class*="TextInput__BottomText"]'),
          ...root.querySelectorAll('[class*="BottomText"]'),
        ];
      } catch (_) {}
      for (const el of matches) {
        const text = String(el.textContent || '').trim();
        if (/Weitere\s+\d+\s+Zeichen/i.test(text) || /Bereit zum Senden/i.test(text)) {
          return { el, text };
        }
      }
    }
    return null;
  }

  function parseComposeSendCharLimit(field) {
    const counter = findComposeCharCounterNear(field);
    if (!counter) return null;
    const composeLen = getFieldCharLength(field);
    const remainingMatch = counter.text.match(/Weitere\s+(\d+)\s+Zeichen/i);
    if (remainingMatch) {
      const remaining = Number(remainingMatch[1]) || 0;
      return { composeLen, remaining, minLen: composeLen + remaining };
    }
    if (/Bereit zum Senden/i.test(counter.text)) {
      return { composeLen, remaining: 0, minLen: composeLen };
    }
    return null;
  }

  function getPreviewCharStats(field, previewText) {
    if (!field) return null;
    const limit = parseComposeSendCharLimit(field);
    if (!limit || limit.minLen <= 0) return null;
    const previewLen = String(previewText || '').length;
    const written = limit.composeLen + previewLen;
    const remaining = Math.max(0, limit.minLen - written);
    return {
      written,
      remaining,
      minLen: limit.minLen,
      ready: remaining === 0,
      label: `${written}/${remaining}`,
    };
  }

  globalThis.chillicollectivoGetPreviewCharStats = function chillicollectivoGetPreviewCharStats(field, previewText) {
    return getPreviewCharStats(field, previewText);
  };

  function findComposeField() {
    const vw = window.innerWidth;
    const vh = window.innerHeight;
    const chatRoot = findChatColumnRoot();
    const scopes = chatRoot ? [chatRoot, document] : [document];
    let best = null;
    let bestScore = -1;
    const selectors = [
      'textarea',
      '[contenteditable="true"]',
      '[contenteditable="plaintext-only"]',
      '[role="textbox"]',
      '[class*="Compose"] textarea',
      '[class*="MessageInput"] textarea',
      '[class*="Conversation"] textarea',
      '[class*="MessageInput"] [contenteditable="true"]',
    ];
    scopes.forEach((scope) => {
      const seen = new Set();
      selectors.forEach((sel) => {
        try { scope.querySelectorAll(sel).forEach((el) => seen.add(el)); } catch (_) {}
      });
      seen.forEach((el) => {
        if (!isVisible(el)) return;
        const r = el.getBoundingClientRect();
        const cx = r.left + r.width / 2;
        if (cx < vw * 0.18 || cx > vw * 0.86) return;
        if (r.bottom < vh * 0.34) return;
        if (r.height < 14 || r.width < 60) return;
        const area = Math.max(1, r.width * r.height);
        const bottomBoost = Math.max(0, vh - r.bottom);
        const score = area * 1.4 + bottomBoost * 3 + (scope === chatRoot ? 5000 : 0);
        if (score > bestScore) {
          bestScore = score;
          best = el;
        }
      });
    });
    return best;
  }

  globalThis.ChillicollectivoTorchwoodAsa = globalThis.ChillicollectivoTorchwoodAsa || {
    findComposeField,
  };
  // Galerie/ASA-Bilder werden nur von der Kategorien-Extension gesteuert, nicht vom Mic.
})();
