#!/usr/bin/env node
/**
 * import-exam9.js — imports ODD variants from /frontend/js/exam9/variants/ into question bank.
 *
 * Usage:
 *   node backend/scripts/import-exam9.js                    # imports v01, v03, ..., v79
 *   node backend/scripts/import-exam9.js --all              # imports ALL 80 variants
 *
 * Idempotent: drops existing exam9 tests/questions before re-import (uses exam9_variant_tests map).
 *
 * For each variant V it creates:
 *   - 1 row in tests       (title="Экзамен 9 — Вариант V", subject_slug='math', show_answers=1)
 *   - 1 row in exam9_variant_tests (V → test.id)
 *   - 10 rows in questions (one per task; allow_html=1, explanation=sol)
 *   - For tasks with opts: rows in options (5 per task, 1 marked correct)
 *   - For tasks without opts: questions.type='short_answer', correct_text=parsed from sol
 *   - 10 rows in test_questions (linking)
 */
'use strict';
const fs   = require('fs');
const path = require('path');
const db   = require('../src/db/db');

const SUBJECT_ID  = 3;        // math (per import-content.js mapping)
const VARIANTS_DIR = path.join(__dirname, '../../frontend/js/exam9/variants');

/* ── Parse answer from sol — supports both <div class="sol-ans">…</div> patterns ─ */
function parseAnswer(sol) {
  if (!sol) return null;
  const m = sol.match(/<div class="sol-ans">([\s\S]*?)<\/div>/);
  if (!m) return null;
  // Remove "Ответ:" prefix and HTML entities/spaces
  let raw = m[1].replace(/<[^>]+>/g, '').replace(/&ensp;|&nbsp;/g, ' ').trim();
  raw = raw.replace(/^Ответ[:\s]*/i, '').trim();
  return raw;
}

/* ── For OPTS tasks: parse the answer letter (а/б/в/г/д) ─ */
function parseAnswerLetter(sol) {
  const ans = parseAnswer(sol);
  if (!ans) return null;
  const m = ans.match(/^([а-дa-e])\s*[\)\.]/i);
  return m ? m[1].toLowerCase() : null;
}

/* ── Find or create an admin user to own the imported tests ─ */
function findCreatedBy() {
  const admin = db.prepare("SELECT id FROM users WHERE role='admin' ORDER BY id LIMIT 1").get();
  if (admin) return admin.id;
  const sys = db.prepare("SELECT id FROM users WHERE email='system@learnspace' OR email='admin@learnspace' LIMIT 1").get();
  if (sys) return sys.id;
  throw new Error('No admin user found — create one first via npm run seed');
}

/* ── Idempotent cleanup ─ */
function cleanupExistingExam9() {
  const oldTestIds = db.prepare('SELECT test_id FROM exam9_variant_tests').all().map(r => r.test_id);
  if (!oldTestIds.length) return 0;

  // Delete questions linked only to exam9 tests (avoid touching shared questions)
  const placeholders = oldTestIds.map(() => '?').join(',');
  const orphanQuestions = db.prepare(`
    SELECT DISTINCT q.id FROM questions q
    JOIN test_questions tq ON tq.question_id = q.id
    WHERE tq.test_id IN (${placeholders})
    AND NOT EXISTS (
      SELECT 1 FROM test_questions tq2
      WHERE tq2.question_id = q.id
        AND tq2.test_id NOT IN (${placeholders})
    )
  `).all(...oldTestIds, ...oldTestIds).map(r => r.id);

  db.transaction(() => {
    // Tests cascade-delete test_questions and exam9_variant_tests rows
    db.prepare(`DELETE FROM tests WHERE id IN (${placeholders})`).run(...oldTestIds);
    // Now delete orphaned questions (their options cascade)
    if (orphanQuestions.length) {
      const qph = orphanQuestions.map(() => '?').join(',');
      db.prepare(`DELETE FROM questions WHERE id IN (${qph})`).run(...orphanQuestions);
    }
  })();

  return oldTestIds.length;
}

/* ── Load a variant from its .js file via Function constructor ─ */
function loadVariant(n) {
  const nn = String(n).padStart(2, '0');
  const src = fs.readFileSync(path.join(VARIANTS_DIR, `v${nn}.js`), 'utf8');
  const scope = {};
  new Function('VARIANTS', src)(scope);
  return scope[n];
}

/* ── Import a single variant ─ */
function importVariant(n, createdBy) {
  const v = loadVariant(n);
  if (!v || !Array.isArray(v.tasks) || !v.tasks.length)
    throw new Error(`Variant ${n}: malformed (no tasks)`);

  const testTitle = `Экзамен 9 — Вариант ${n}`;
  const desc      = `Экзаменационный вариант №${n} (математика, 9 класс). ${v.tasks.length} задач с разбором.`;

  return db.transaction(() => {
    const { lastInsertRowid: testId } = db.prepare(
      `INSERT INTO tests (title, subject_slug, description, created_by, show_answers, time_limit)
       VALUES (?, 'math', ?, ?, 1, NULL)`
    ).run(testTitle, desc, createdBy);

    db.prepare('INSERT INTO exam9_variant_tests (variant, test_id) VALUES (?, ?)').run(n, testId);

    const insQ   = db.prepare(
      `INSERT INTO questions (subject_id, text, type, correct_text, explanation, allow_html, source_type, year)
       VALUES (?, ?, ?, ?, ?, 1, 'экзамен 9', 2025)`
    );
    const insOpt = db.prepare(
      'INSERT INTO options (question_id, text, is_correct, order_index) VALUES (?,?,?,?)'
    );
    const insTQ  = db.prepare(
      'INSERT INTO test_questions (test_id, question_id, order_index) VALUES (?,?,?)'
    );

    let questionCount = 0, optsCount = 0;
    v.tasks.forEach((t, i) => {
      const textWithFigure = t.figure ? `${t.text}<div class="task-figure" style="margin-top:12px">${t.figure}</div>` : t.text;
      const explanation    = t.sol || '';

      if (t.opts && t.opts.length) {
        const correctLetter = parseAnswerLetter(t.sol);
        const { lastInsertRowid: qid } = insQ.run(
          SUBJECT_ID, textWithFigure, 'single', null, explanation
        );
        t.opts.forEach(([letter, optText], idx) => {
          const isCorrect = correctLetter && letter.toLowerCase() === correctLetter ? 1 : 0;
          insOpt.run(qid, optText, isCorrect, idx);
          optsCount++;
        });
        insTQ.run(testId, qid, i);
        questionCount++;
      } else {
        const correctText = parseAnswer(t.sol);
        const { lastInsertRowid: qid } = insQ.run(
          SUBJECT_ID, textWithFigure, 'short_answer', correctText, explanation
        );
        insTQ.run(testId, qid, i);
        questionCount++;
      }
    });

    return { testId, questionCount, optsCount };
  })();
}

/* ── Main ─ */
function main() {
  const all = process.argv.includes('--all');
  const variantNumbers = all
    ? Array.from({ length: 80 }, (_, i) => i + 1)
    : Array.from({ length: 40 }, (_, i) => i * 2 + 1);  // 1, 3, 5, ..., 79

  console.log(`[exam9-import] Target: ${variantNumbers.length} variants (${all ? 'ALL' : 'ODD'})`);

  const createdBy = findCreatedBy();
  console.log(`[exam9-import] Owner user_id: ${createdBy}`);

  const cleaned = cleanupExistingExam9();
  if (cleaned) console.log(`[exam9-import] Cleaned ${cleaned} existing exam9 test(s)`);

  let totalQ = 0, totalOpts = 0, errors = 0;
  for (const n of variantNumbers) {
    try {
      const { questionCount, optsCount, testId } = importVariant(n, createdBy);
      console.log(`  v${String(n).padStart(2, '0')} → test #${testId} · ${questionCount} q · ${optsCount} opts`);
      totalQ += questionCount;
      totalOpts += optsCount;
    } catch (e) {
      console.error(`  v${String(n).padStart(2, '0')} FAILED: ${e.message}`);
      errors++;
    }
  }

  console.log(`\n[exam9-import] Done: ${variantNumbers.length - errors}/${variantNumbers.length} variants, ${totalQ} questions, ${totalOpts} options`);
  if (errors) process.exit(2);
}

main();
