#!/usr/bin/env node

const fs = require('fs');
const path = require('path');

const repoRoot = path.resolve(__dirname, '..');
const rulesPath = path.join(repoRoot, 'database', 'rules', 'rules-database.json');

const data = JSON.parse(fs.readFileSync(rulesPath, 'utf8'));
const rules = data.rules || [];

const scenarios = [
  {
    actor: 'Player',
    moment: 'Tyranid Warrior hits Brother Lucian; player checks whether a Reaction can cancel it.',
    query: 'dodge',
    expected: ['Dodge']
  },
  {
    actor: 'GM',
    moment: 'Heavy bolter lays down fire across a corridor.',
    query: 'suppressing fire pinning',
    expected: ['Suppressing Fire', 'Pinning']
  },
  {
    actor: 'Player',
    moment: 'Devastator fires full auto and needs additional hit rules.',
    query: 'full auto burst',
    expected: ['Full Auto Burst']
  },
  {
    actor: 'GM',
    moment: 'A mob of gaunts becomes one mass enemy.',
    query: 'horde magnitude damage',
    expected: ['Hordes']
  },
  {
    actor: 'Player',
    moment: 'Librarian rolls psychic backlash.',
    query: 'perils of the warp',
    expected: ['Perils of the Warp']
  },
  {
    actor: 'GM',
    moment: 'Kill-team takes blast damage in Squad Mode.',
    query: 'cohesion damage',
    expected: ['Cohesion Damage']
  },
  {
    actor: 'Player',
    moment: 'Mission prep pauses to buy gear.',
    query: 'requisition renown',
    expected: ['Requisition', 'Renown']
  },
  {
    actor: 'GM',
    moment: 'Enemy causes Fear and the table needs the modifier.',
    query: 'fear test',
    expected: ['Fear']
  }
];

function includes(value, term) {
  return String(value || '').toLowerCase().includes(term);
}

function score(rule, query) {
  const term = query.toLowerCase();
  const tokens = term.split(/\s+/).filter(Boolean);
  const title = String(rule.title || '').toLowerCase();
  const summary = String(rule.summary || '').toLowerCase();
  const content = String(rule.content || '').toLowerCase();
  const tags = (rule.tags || []).map(v => String(v).toLowerCase());
  const aliases = (rule.aliases || []).map(v => String(v).toLowerCase());
  const tokenHits = tokens.reduce((sum, token) => {
    return sum +
      (title.includes(token) ? 8 : 0) +
      (aliases.some(a => a.includes(token)) ? 6 : 0) +
      (tags.some(a => a.includes(token)) ? 4 : 0) +
      (summary.includes(token) ? 3 : 0) +
      (content.includes(token) ? 1 : 0);
  }, 0);
  return (title === term ? 100 : 0) +
    (aliases.includes(term) ? 90 : 0) +
    (title.startsWith(term) ? 50 : 0) +
    (includes(rule.title, term) ? 20 : 0) +
    (aliases.some(a => a.includes(term)) ? 18 : 0) +
    (tags.some(t => t.includes(term)) ? 15 : 0) +
    (includes(rule.summary, term) ? 8 : 0) +
    Number(rule.midgamePriority || 0) +
    tokenHits +
    (includes(rule.content, term) ? 1 : 0);
}

function search(query, limit = 5) {
  const term = query.toLowerCase();
  const tokens = term.split(/\s+/).filter(Boolean);
  return rules
    .filter(rule => {
      const haystacks = [
        rule.title,
        rule.summary,
        rule.content,
        rule.category,
        ...(rule.tags || []),
        ...(rule.aliases || [])
      ].map(v => String(v || '').toLowerCase());
      return tokens.every(token => haystacks.some(v => v.includes(token))) ||
        haystacks.some(v => v.includes(term));
    })
    .sort((a, b) => score(b, query) - score(a, query))
    .slice(0, limit);
}

let failures = 0;
console.log('Mid-play rules lookup simulation\n');

for (const scenario of scenarios) {
  const results = search(scenario.query);
  const titles = results.map(r => r.title);
  const ok = scenario.expected.some(expected => titles.slice(0, 3).includes(expected));
  if (!ok) failures += 1;

  console.log(`${scenario.actor}: ${scenario.moment}`);
  console.log(`  Query: ${scenario.query}`);
  console.log(`  Top results: ${titles.slice(0, 3).join(' | ') || '(none)'}`);
  if (results[0]) {
    const page = results[0].page ? ` p.${results[0].page}${results[0].pageEnd && results[0].pageEnd !== results[0].page ? `-${results[0].pageEnd}` : ''}` : '';
    console.log(`  Opens: ${results[0].sourceAbbr || results[0].source}${page} [${results[0].sourceMethod}, ${Math.round(Number(results[0].confidence || 0) * 100)}%]`);
  }
  console.log(`  ${ok ? 'PASS' : 'FAIL'}\n`);
}

if (failures) {
  console.error(`${failures} mid-play lookup scenario(s) failed.`);
  process.exit(1);
}

console.log('All mid-play lookup scenarios passed.');
