// engine/db/migrations/004-pull-requests.js
//
// Phase 3: move pull-requests.json (central + per-project) into a
// `pull_requests` table.
//
// Same hybrid schema as `work_items`: typed projection columns for hot
// filters (scope/status/agent/branch/timestamps), plus a `data` TEXT
// column holding the full record JSON so future fields land transparently.
//
// `scope` keys the file the record came from: 'central' for
// <MINIONS_DIR>/pull-requests.json, otherwise the project name (matches
// the directory under projects/<name>/). Per-scope writes diff against
// that scope's rows so a mutation on one project's file never touches
// another's.
//
// Backfill: walk central + every projects/<name>/pull-requests.json. The
// JSON files stay on disk as a dual-write mirror so legacy direct-readers
// continue to function while we migrate them in Phase 3.5.

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

function _resolveMinionsDir() {
  const envHome = process.env.MINIONS_TEST_DIR || process.env.MINIONS_HOME;
  if (envHome) return envHome;
  try { return require('../../shared').MINIONS_DIR; } catch { return null; }
}

function _toMs(v) {
  if (v == null) return null;
  if (typeof v === 'number') return Number.isFinite(v) ? v : null;
  const parsed = Date.parse(v);
  return Number.isFinite(parsed) ? parsed : null;
}

function _readJsonArray(filePath) {
  try {
    const raw = fs.readFileSync(filePath, 'utf8');
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return [];
  }
}

function _listProjectDirs(minionsDir) {
  const projectsRoot = path.join(minionsDir, 'projects');
  let entries;
  try { entries = fs.readdirSync(projectsRoot, { withFileTypes: true }); }
  catch { return []; }
  const out = [];
  for (const e of entries) {
    if (!e.isDirectory()) continue;
    if (e.name.startsWith('.')) continue;  // .archived + any other hidden sidecars
    out.push(e.name);
  }
  return out;
}

module.exports = {
  version: 4,
  description: 'pull_requests: schema + pull-requests.json backfill (central + per-project)',
  up(db) {
    db.exec(`
      CREATE TABLE pull_requests (
        id              TEXT NOT NULL,
        scope           TEXT NOT NULL,
        status          TEXT NOT NULL,
        review_status   TEXT,
        agent           TEXT,
        branch          TEXT,
        pr_number       INTEGER,
        created_at      INTEGER,
        last_polled_at  INTEGER,
        data            TEXT NOT NULL,
        updated_at      INTEGER NOT NULL,
        PRIMARY KEY (scope, id)
      );
      CREATE INDEX idx_pr_status            ON pull_requests(status);
      CREATE INDEX idx_pr_scope_status      ON pull_requests(scope, status);
      CREATE INDEX idx_pr_agent             ON pull_requests(agent);
      CREATE INDEX idx_pr_branch            ON pull_requests(branch);
    `);

    const minionsDir = _resolveMinionsDir();
    if (!minionsDir) return;

    const insert = db.prepare(`
      INSERT INTO pull_requests (id, scope, status, review_status, agent, branch, pr_number, created_at, last_polled_at, data, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `);

    const now = Date.now();
    let inserted = 0;

    const backfillFile = (scope, filePath) => {
      const rows = _readJsonArray(filePath);
      for (const pr of rows) {
        if (!pr || typeof pr !== 'object' || !pr.id) continue;
        try {
          insert.run(
            String(pr.id),
            scope,
            String(pr.status || 'active'),
            pr.reviewStatus || null,
            pr.agent || null,
            pr.branch || null,
            Number.isFinite(pr.prNumber) ? pr.prNumber : null,
            _toMs(pr.created),
            _toMs(pr.lastPolledAt || pr.lastPolled),
            JSON.stringify(pr),
            now,
          );
          inserted += 1;
        } catch {
          // Duplicate (scope, id) — skip. Defensive against malformed files.
        }
      }
    };

    backfillFile('central', path.join(minionsDir, 'pull-requests.json'));
    for (const projectName of _listProjectDirs(minionsDir)) {
      backfillFile(projectName, path.join(minionsDir, 'projects', projectName, 'pull-requests.json'));
    }

    // eslint-disable-next-line no-console
    console.log(`[db-migrate] v4: backfilled ${inserted} pull requests; pull-requests.json files kept as dual-write mirrors`);
  },
};
