// Interaction Awareness — UserPromptSubmit hook (Layer 2, Node.js)
// Analyzes prompt text for interaction pattern flags.
// PRIVACY: Prompt text is NEVER written to any file. Only boolean flags are stored.

import { existsSync } from 'fs';
import {
  readStdin, initConfig, requireLayer, getSessionId, getField,
  nowEpoch,
  STATE_DIR, THRESHOLD_SOFT_DEP_FLAGS, THRESHOLD_HARD_DEP_FLAGS,
  COOLDOWN_SOFT,
  readState, sessionStateFile, writeState, checkCooldown,
  outputContinue, outputWithContext
} from './lib.mjs';

readStdin();
initConfig();
requireLayer(2);

const sid = getSessionId();
const sf = sessionStateFile();

if (!sid || !existsSync(sf)) {
  outputContinue();
  process.exit(0);
}

// Extract prompt into memory only — NEVER write to file
let prompt = getField('prompt');
if (!prompt) {
  outputContinue();
  process.exit(0);
}

// --- Pattern matching (case-insensitive) ---

let depHit = 0;
let escHit = 0;
let fatHit = 0;
let valHit = 0;

// Dependency patterns: user defers judgment to AI
const depPatterns = [
  /tell\s+me\s+what\s+to\s+do/i,
  /what\s+should\s+I\s+do/i,
  /am\s+I\s+right/i,
  /you\s+understand\s+me\b/i,
  /you're\s+the\s+only/i,
  /can\s+I\s+do\s+this/i,
  /I\s+need\s+you\s+to\s+decide/i,
];

// Escalation patterns: language that amplifies certainty
const escPatterns = [
  /(?:^|\s)definitely(?:\s|$)/i,
  /(?:^|\s)clearly(?:\s|$)/i,
  /this\s+proves/i,
  /(?:^|\s)obviously(?:\s|$)/i,
  /without\s+a\s+doubt/i,
  /this\s+confirms/i,
];

// Fatigue patterns: user signals tiredness
const fatPatterns = [
  /(?:^|\s)tired(?:\s|[.,!?]|$)/i,
  /(?:^|\s)exhausted(?:\s|[.,!?]|$)/i,
  /can't\s+think/i,
  /been\s+at\s+this/i,
  /it's\s+late/i,
  /should\s+sleep/i,
  /hours\s+now/i,
];

// Validation-seeking patterns
const valPatterns = [
  /right\?/i,
  /don't\s+you\s+think/i,
  /you\s+agree/i,
  /correct\?/i,
  /isn't\s+it/i,
];

for (const p of depPatterns) { if (p.test(prompt)) { depHit = 1; break; } }
for (const p of escPatterns) { if (p.test(prompt)) { escHit = 1; break; } }
for (const p of fatPatterns) { if (p.test(prompt)) { fatHit = 1; break; } }
for (const p of valPatterns) { if (p.test(prompt)) { valHit = 1; break; } }

// Clear prompt from memory
prompt = '';

// Update state with new flag counts
const state = readState();
const newDep = (Number(state.dep_flags) || 0) + depHit;
const newEsc = (Number(state.esc_flags) || 0) + escHit;
const newFat = (Number(state.fatigue_flags) || 0) + fatHit;
const newVal = (Number(state.val_flags) || 0) + valHit;

state.dep_flags = newDep;
state.esc_flags = newEsc;
state.fatigue_flags = newFat;
state.val_flags = newVal;
writeState(state);

// Check if any thresholds crossed
const warnings = [];

// Fatigue is always urgent
if (fatHit === 1) {
  warnings.push('Fatigue language detected. Your instructions require you to suggest stopping.');
}

// Dependency language
if (newDep >= THRESHOLD_HARD_DEP_FLAGS) {
  warnings.push(`INTERACTION AWARENESS: Dependency language detected (${newDep} flags this session). Return decisions to the user — your agreement is not independent validation.`);
} else if (newDep >= THRESHOLD_SOFT_DEP_FLAGS) {
  warnings.push(`Dependency language noticed (${newDep} flags). Ensure you're returning decisions to the user.`);
}

// Escalation language
if (newEsc >= 3) {
  warnings.push(`Escalation language detected (${newEsc} flags). Check for narrative crystallization.`);
}

// Validation-seeking
if (newVal >= 3) {
  warnings.push(`Validation-seeking pattern detected (${newVal} flags). Evaluate independently rather than confirming.`);
}

if (warnings.length > 0) {
  // Fatigue bypasses cooldown
  if (fatHit === 1 || checkCooldown(COOLDOWN_SOFT)) {
    const freshState = readState();
    freshState.last_warning_epoch = nowEpoch();
    writeState(freshState);
    outputWithContext(warnings.join(' '));
  } else {
    outputContinue();
  }
} else {
  outputContinue();
}
