import { db } from '../config/database.js';
import { emails, contacts } from '../db/schema.js';
import { eq, and, or, ne, isNotNull } from 'drizzle-orm';
import { logger } from '../utils/logger.js';

/**
 * Fix emails that have wrong contactId
 *
 * This script finds emails where the contactId doesn't match the actual contact
 * based on the from/to fields, and updates them to the correct contactId.
 *
 * Run with: node src/scripts/fix-wrong-contact-associations.js
 */

async function fixWrongContactAssociations() {
  try {
    logger.info('🔧 Starting to fix wrong contact associations...');

    // Get all contacts grouped by email account
    const allContacts = await db
      .select()
      .from(contacts)
      .orderBy(contacts.emailAccountId, contacts.email);

    logger.info(`Found ${allContacts.length} contacts to process`);

    let totalFixed = 0;
    let totalChecked = 0;

    // Process each contact
    for (const contact of allContacts) {
      logger.info(`\n📧 Processing contact: ${contact.email} (${contact.name})`);

      // Find emails that belong to this contact but have wrong contactId
      // Email belongs to contact if from === contact.email OR to === contact.email
      const wrongEmails = await db
        .select()
        .from(emails)
        .where(
          and(
            eq(emails.emailAccountId, contact.emailAccountId),
            ne(emails.contactId, contact.id), // Has different contactId
            or(
              eq(emails.from, contact.email),
              eq(emails.to, contact.email)
            )
          )
        );

      totalChecked += wrongEmails.length;

      if (wrongEmails.length > 0) {
        logger.info(`  ⚠️  Found ${wrongEmails.length} emails with wrong contactId`);

        for (const email of wrongEmails) {
          // Get old contact name for logging
          const [oldContact] = await db
            .select()
            .from(contacts)
            .where(eq(contacts.id, email.contactId))
            .limit(1);

          logger.info(`  📬 Fixing email "${email.subject}"`);
          logger.info(`     From: ${email.from} → To: ${email.to}`);
          logger.info(`     Old contact: ${oldContact?.email || 'unknown'} → New contact: ${contact.email}`);

          // Update to correct contactId
          await db
            .update(emails)
            .set({ contactId: contact.id })
            .where(eq(emails.id, email.id));

          totalFixed++;
        }

        logger.success(`  ✅ Fixed ${wrongEmails.length} emails for ${contact.email}`);
      } else {
        logger.info(`  ✅ No wrong associations found for ${contact.email}`);
      }
    }

    logger.success(`\n✅ Fix completed!
   - Total contacts checked: ${allContacts.length}
   - Total wrong emails found: ${totalChecked}
   - Total emails fixed: ${totalFixed}
`);

    return { totalContacts: allContacts.length, totalChecked, totalFixed };
  } catch (error) {
    logger.error('Error fixing contact associations', error);
    throw error;
  }
}

// Run the script
fixWrongContactAssociations()
  .then((result) => {
    logger.success('Script finished successfully', result);
    process.exit(0);
  })
  .catch((error) => {
    logger.error('Script failed', error);
    process.exit(1);
  });
