import type { EmotionMetadata } from "./memory-schema.js";
import { isEmotionScoringEnabled } from "./memory-schema.js";

const NEGATIVE_SIGNALS: string[] = [
  // English
  "fail", "failed", "failure", "broken", "bug", "error", "wrong", "crash",
  "frustrat", "hate", "terrible", "awful", "annoying", "pain", "stuck",
  "problem", "issue", "mess", "ugly", "worst",
  // Chinese
  "失败", "痛苦", "困扰", "崩溃", "报错", "出错", "难受", "烦",
  "卡住", "折腾", "头疼", "坑", "讨厌", "不喜欢", "糟糕", "恶心",
];

const POSITIVE_SIGNALS: string[] = [
  // English
  "solved", "fixed", "works", "perfect", "great", "love", "excellent",
  "success", "breakthrough", "finally", "awesome", "beautiful", "clean",
  "elegant", "smooth", "done", "shipped",
  // Chinese
  "搞定", "成功", "突破", "完美", "太好了", "顺利", "解决", "漂亮",
  "优雅", "通过", "上线", "喜欢", "开心", "厉害",
];

const HIGH_AROUSAL_SIGNALS: string[] = [
  "!", "!!", "urgent", "critical", "immediately", "ASAP", "emergency",
  "紧急", "立刻", "马上", "赶紧", "救命",
];

/** Chinese negation prefixes that flip positive → negative */
const CN_NEGATION_PREFIXES = ["不", "没", "非", "无", "别", "未"];

function clamp(value: number, min: number, max: number): number {
  return Math.max(min, Math.min(max, value));
}

/**
 * Count positive signal matches, handling Chinese negation.
 * "不喜欢" → skip positive, add to negatedCount (caller adds to negative).
 * Returns { positive, negated } counts.
 */
function countPositiveSignals(lower: string): { positive: number; negated: number } {
  let positive = 0;
  let negated = 0;
  for (const signal of POSITIVE_SIGNALS) {
    const s = signal.toLowerCase();
    const idx = lower.indexOf(s);
    if (idx === -1) continue;
    const isNegated = idx > 0 && CN_NEGATION_PREFIXES.some(neg => lower.substring(idx - neg.length, idx) === neg);
    if (isNegated) {
      negated++;
    } else {
      positive++;
    }
  }
  return { positive, negated };
}

/**
 * Detect emotional valence and arousal from text using keyword heuristics.
 * Zero LLM cost. Returns neutral emotion for empty text.
 */
export function detectEmotion(text: string): EmotionMetadata {
  if (!text || text.length === 0) {
    return { valence: 0, arousal: 0, label: "neutral", salience: 0, source: "keyword" };
  }

  const lower = text.toLowerCase();

  const negCount = NEGATIVE_SIGNALS.filter(s => lower.includes(s.toLowerCase())).length;
  const { positive: posCount, negated: negatedPosCount } = countPositiveSignals(lower);
  const arousalCount = HIGH_AROUSAL_SIGNALS.filter(s => text.includes(s)).length;

  // Negated positive signals (e.g. "不开心") count as additional negatives
  const valence = clamp((posCount - negCount - negatedPosCount) * 0.3, -1, 1);
  const arousal = clamp(arousalCount * 0.25, 0, 1);
  const label = valence > 0.25 ? "positive" : valence < -0.25 ? "negative" : "neutral";

  // Salience: composite mnemonic significance — average of emotional intensity and arousal
  const salience = clamp((Math.abs(valence) + arousal) / 2, 0, 1);

  return { valence, arousal, label, salience, source: "keyword" };
}

/**
 * Conditionally detect emotion. Returns null when feature flag is off.
 */
export function detectEmotionIfEnabled(text: string): EmotionMetadata | null {
  if (!isEmotionScoringEnabled()) return null;
  return detectEmotion(text);
}
