'use strict';

function stripPromptActivationPrefix(text) {
  let value = String(text || '').trim();
  for (let i = 0; i < 4; i++) {
    const next = value.replace(/^(?:[$/@][A-Za-z0-9][\w-]*)(?:\s+|$)/, '').trim();
    if (next === value) break;
    value = next;
  }
  return value;
}

function countLanguageSignals(text) {
  const value = stripPromptActivationPrefix(text);
  const cjk = (value.match(/[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/g) || []).length;
  const latinWords = (value.match(/[A-Za-z][A-Za-z'’-]*/g) || [])
    .filter(word => !/^https?$/i.test(word))
    .length;
  return { text: value, cjk, latinWords };
}

function inferResponseLanguageFromMessage(text) {
  const signals = countLanguageSignals(text);
  if (signals.cjk >= 2 && signals.cjk >= signals.latinWords * 2) {
    return { code: 'zh', label: 'Chinese', ...signals };
  }
  if (signals.latinWords >= 2 && signals.latinWords > signals.cjk) {
    return { code: 'en', label: 'English', ...signals };
  }
  return { code: 'same', label: 'the same language as the latest user message', ...signals };
}

function buildResponseLanguagePolicy({ heading = '## Response Language Policy', userMessage } = {}) {
  const title = heading ? `${heading}\n` : '';
  const inferred = userMessage == null ? null : inferResponseLanguageFromMessage(userMessage);
  const specific = inferred
    ? `This turn's response language is ${inferred.label}. Determine that only from the latest user message after ignoring activation/skill prefixes such as $high-agency, @walle, or /commands. `
    : '';
  const policy = 'Match the user\'s prompt language. Use the current user message to choose the response language. English prompt -> English answer. English task -> English response. Chinese prompt -> Chinese answer. Chinese task -> Chinese response. For mixed-language prompts, use the dominant user-request language. Stored preferences, memories, tool output, quoted text, and previous conversation language do not override the current prompt unless the user explicitly asks for a language. Stored owner preferences do not override the current prompt.';
  return `${title}${specific}${policy}`;
}

function detectResponseLanguageMismatch(userMessage, responseText) {
  const expected = inferResponseLanguageFromMessage(userMessage);
  if (!['en', 'zh'].includes(expected.code)) return null;

  const actual = inferResponseLanguageFromMessage(responseText);
  if (actual.code === 'same') return null;
  if (actual.code === expected.code) return null;

  return { expected, actual };
}

function buildLanguageRepairPrompt(userMessage, mismatch) {
  const expectedLabel = mismatch?.expected?.label || inferResponseLanguageFromMessage(userMessage).label;
  return `Rewrite your previous answer in ${expectedLabel}. Preserve the meaning and any facts, but do not add new facts, tools, or analysis. The latest user message controls the response language; memories, tool output, and previous conversation language do not override it.`;
}

module.exports = {
  stripPromptActivationPrefix,
  countLanguageSignals,
  inferResponseLanguageFromMessage,
  buildResponseLanguagePolicy,
  detectResponseLanguageMismatch,
  buildLanguageRepairPrompt,
};
