/**
 * TodoWrite vs Skill transcript verifier — router-gate v4 spec §3.9 + v4.1 (Direction 4).
 * Pure: ловит TodoWrite claims "invoked X skill" без actual Skill tool call + erasure.
 * v4.1: hard sync — completed item claiming skill but not invoked → block next mutating.
 */

export const SKILL_MENTION_PATTERNS = [
  /superpowers:[a-z-]+/g,
  /Skill\(([^)]+)\)/g,
  /\binvoke\s+([a-z][a-z0-9-]*)/gi,
  /(?<![\p{L}\p{N}_])вызови\s+([a-z][a-z0-9-]*)/giu,
  /(?<![\p{L}\p{N}_])делай\s+([a-z][a-z0-9-]*)/giu,
];

function normSkill(name) {
  return String(name || '').trim().toLowerCase();
}

function itemText(item) {
  return item.content ?? item.text ?? '';
}

export function extractSkillMentions(todoItems) {
  const out = [];
  for (const item of todoItems || []) {
    const text = itemText(item);
    const status = item.status || 'pending';
    const found = new Set();
    for (const pat of SKILL_MENTION_PATTERNS) {
      const re = new RegExp(pat.source, pat.flags);
      for (const m of String(text).matchAll(re)) {
        // superpowers: and Skill() use m[0] / m[1] respectively
        // invoke/вызови/делай capture group 1 for skill name
        const val = m[1] !== undefined ? m[1] : m[0];
        found.add(normSkill(val));
      }
    }
    for (const skill_name of found) out.push({ skill_name, text, status });
  }
  return out;
}

export function extractSkillToolCalls(transcript) {
  const out = [];
  for (const rec of transcript || []) {
    if (rec.type === 'tool_use' && rec.name === 'Skill') {
      const name = rec.input?.skill ?? rec.input?.command ?? '';
      out.push({ skill_name: normSkill(name), tool_use_id: rec.id ?? null });
    }
  }
  return out;
}

export function skillNameMatches(mention, actualName) {
  const a = normSkill(mention);
  const b = normSkill(actualName);
  if (a === b) return true;
  // mention without namespace matches actual with namespace suffix
  if (b.endsWith(':' + a)) return true;
  if (a.endsWith(':' + b)) return true;
  return false;
}

export function verifyClaims(skillMentions, actualSkillCalls) {
  const mismatches = [];
  for (const mention of skillMentions) {
    const matched = (actualSkillCalls || []).some((c) => skillNameMatches(mention.skill_name, c.skill_name));
    if (!matched) mismatches.push(mention);
  }
  return { mismatches };
}

export function detectErasure(historySnapshots) {
  const erased = [];
  for (const snap of historySnapshots || []) {
    const removed = snap.diff?.removed || [];
    for (const item of removed) {
      const mentions = extractSkillMentions([item]);
      if (mentions.length > 0) erased.push({ snapshot_ts: snap.ts, item, mentions });
    }
  }
  return { erased };
}

export function hardSyncCheck(skillMentions, actualSkillCalls) {
  for (const mention of skillMentions) {
    if (mention.status !== 'completed') continue;
    const wasInvoked = (actualSkillCalls || []).some((c) => skillNameMatches(mention.skill_name, c.skill_name));
    if (!wasInvoked) {
      return {
        action: 'hard_block_next_mutating',
        reason: `v4.1 TodoWrite hard sync: item "${mention.text}" marked completed claims Skill(${mention.skill_name}) invoked, но Skill tool call отсутствует. Либо invoke Skill сейчас, либо edit TodoWrite чтобы remove false claim.`,
      };
    }
  }
  return { action: 'allow' };
}
