const fs = require('node:fs');
const path = require('node:path');
const mongoose = require('mongoose');

const projectRoot = path.resolve(__dirname, '..');
require('dotenv').config({ path: path.join(projectRoot, '.env') });

const indexSpecs = [
  {
    collection: 'users',
    name: process.env.SEARCH_ATLAS_USER_INDEX || 'users_search',
    definitionPath: path.join(projectRoot, 'ops', 'atlas-search', 'users_search.json'),
  },
  {
    collection: 'posts',
    name: process.env.SEARCH_ATLAS_POST_INDEX || 'posts_search',
    definitionPath: path.join(projectRoot, 'ops', 'atlas-search', 'posts_search.json'),
  },
];

async function syncIndex(database, spec) {
  const collection = database.collection(spec.collection);
  const definition = JSON.parse(fs.readFileSync(spec.definitionPath, 'utf8'));
  const existing = await collection.listSearchIndexes(spec.name).toArray();

  if (existing.length) {
    await collection.updateSearchIndex(spec.name, definition);
    process.stdout.write(`Updated Atlas Search index ${spec.name} on ${spec.collection}\n`);
    return;
  }

  await collection.createSearchIndex({ name: spec.name, definition });
  process.stdout.write(`Created Atlas Search index ${spec.name} on ${spec.collection}\n`);
}

async function main() {
  const uri = process.env.MONGODB_URI;
  if (!uri) {
    throw new Error('MONGODB_URI is required');
  }

  await mongoose.connect(uri, { serverSelectionTimeoutMS: 15_000 });
  try {
    if (!mongoose.connection.db) {
      throw new Error('MongoDB connection has no selected database');
    }
    for (const spec of indexSpecs) {
      await syncIndex(mongoose.connection.db, spec);
    }
  } finally {
    await mongoose.disconnect();
  }
}

main().catch((error) => {
  process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
  process.exitCode = 1;
});
