const path = require('path');
const mongoose = require('mongoose');
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
require('dotenv').config({ path: path.resolve(__dirname, '..', '.env') });
const { askQuestion, silentExit } = require('./helpers');
const connect = require('./connect');
const { batchResetMeiliFlags } = require('~/db/utils');

(async () => {
  await connect();

  console.purple('---------------------------------------');
  console.purple('Reset MeiliSearch Synchronization Flags');
  console.purple('---------------------------------------');
  console.yellow('\nThis script will reset the MeiliSearch indexing flags in MongoDB.');
  console.yellow('Use this when MeiliSearch data has been deleted or corrupted,');
  console.yellow('and you need to trigger a full re-synchronization.\n');

  const confirm = await askQuestion(
    'Are you sure you want to reset all MeiliSearch sync flags? (y/N): ',
  );

  if (confirm.toLowerCase() !== 'y') {
    console.orange('Operation cancelled.');
    silentExit(0);
  }

  try {
    const clearProgress = () => process.stdout.write('\r' + ' '.repeat(70) + '\r');

    // Reset _meiliIndex flags for messages
    console.cyan('\nResetting message sync flags...');
    const messages = mongoose.connection.db.collection('messages');
    const messageModifiedCount = await batchResetMeiliFlags(messages);
    clearProgress();
    console.green(`✓ Reset ${messageModifiedCount} message sync flags`);

    // Reset _meiliIndex flags for conversations
    console.cyan('\nResetting conversation sync flags...');
    const conversationsCollection = mongoose.connection.db.collection('conversations');
    const conversationModifiedCount = await batchResetMeiliFlags(conversationsCollection);
    clearProgress();
    console.green(`✓ Reset ${conversationModifiedCount} conversation sync flags`);

    // Query to count only non-expired documents that are queued for sync (_meiliIndex: false)
    // This represents documents that need to be indexed, not the total collection size
    const queryTotal = { expiredAt: null, _meiliIndex: false };

    // Get current counts of documents queued for sync
    const totalMessages = await mongoose.connection.db
      .collection('messages')
      .countDocuments(queryTotal);
    const totalConversations = await mongoose.connection.db
      .collection('conversations')
      .countDocuments(queryTotal);

    console.purple('\n---------------------------------------');
    console.green('MeiliSearch sync flags have been reset successfully!');
    console.cyan(`\nDocuments queued for sync:`);
    console.cyan(`Messages: ${totalMessages}`);
    console.cyan(`Conversations: ${totalConversations}`);
    console.yellow('\nThe next time QognyX starts or performs a sync check,');
    console.yellow('all data will be re-indexed into MeiliSearch.');
    console.purple('---------------------------------------\n');

    // Ask if user wants to see advanced options
    const showAdvanced = await askQuestion('Show advanced options? (y/N): ');

    if (showAdvanced.toLowerCase() === 'y') {
      console.cyan('\nAdvanced Options:');
      console.yellow('1. To trigger immediate sync, restart QognyX');
      console.yellow('2. To disable sync, set MEILI_NO_SYNC=true in .env');
      console.yellow(
        '3. To adjust sync batch size, set MEILI_SYNC_BATCH_SIZE in .env (default: 100)',
      );
      console.yellow('4. To adjust sync delay, set MEILI_SYNC_DELAY_MS in .env (default: 100ms)');
      console.yellow(
        '5. To change sync threshold, set MEILI_SYNC_THRESHOLD in .env (default: 1000)\n',
      );
    }

    silentExit(0);
  } catch (error) {
    console.red('\nError resetting MeiliSearch sync flags:');
    console.error(error);
    silentExit(1);
  }
})();

process.on('uncaughtException', (err) => {
  if (!err.message.includes('fetch failed')) {
    console.error('There was an uncaught error:');
    console.error(err);
  }

  if (err.message.includes('fetch failed')) {
    return;
  } else {
    process.exit(1);
  }
});
