import 'dotenv/config';
import { drizzle } from 'drizzle-orm/node-postgres';
import pkg from 'pg';
const { Pool } = pkg;
import { users, emailAccounts, contacts, emails } from '../schema.js';
import { sql } from 'drizzle-orm';

/**
 * Migration script to move from single email per user to multiple email accounts
 *
 * Steps:
 * 1. Create email_accounts table
 * 2. Migrate existing user emails to email_accounts (as primary)
 * 3. Add email_account_id to contacts and emails tables
 * 4. Update existing contacts and emails to reference new email accounts
 */

const pool = new Pool({
  host: process.env.DB_HOST || 'localhost',
  port: parseInt(process.env.DB_PORT || '5432'),
  user: process.env.DB_USER || 'admin',
  password: process.env.DB_PASSWORD || 'heslo123',
  database: process.env.DB_NAME || 'crm',
});

const db = drizzle(pool);

async function migrateToEmailAccounts() {
  console.log('🚀 Starting migration to email accounts...\n');

  try {
    // Step 1: Create email_accounts table
    console.log('Step 1: Creating email_accounts table...');
    await db.execute(sql`
      CREATE TABLE IF NOT EXISTS "email_accounts" (
        "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
        "user_id" uuid NOT NULL,
        "email" text NOT NULL,
        "email_password" text NOT NULL,
        "jmap_account_id" text NOT NULL,
        "is_primary" boolean DEFAULT false NOT NULL,
        "is_active" boolean DEFAULT true NOT NULL,
        "created_at" timestamp DEFAULT now() NOT NULL,
        "updated_at" timestamp DEFAULT now() NOT NULL
      )
    `);

    await db.execute(sql`
      ALTER TABLE "email_accounts"
      ADD CONSTRAINT "email_accounts_user_id_users_id_fk"
      FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
      ON DELETE cascade ON UPDATE no action
    `);
    console.log('✅ email_accounts table created\n');

    // Step 2: Migrate existing user emails to email_accounts
    console.log('Step 2: Migrating existing user emails to email_accounts...');
    const usersWithEmail = await db.execute(sql`
      SELECT id, email, email_password, jmap_account_id
      FROM users
      WHERE email IS NOT NULL
        AND email_password IS NOT NULL
        AND jmap_account_id IS NOT NULL
    `);

    console.log(`Found ${usersWithEmail.rows.length} users with email accounts`);

    for (const user of usersWithEmail.rows) {
      await db.execute(sql`
        INSERT INTO email_accounts (user_id, email, email_password, jmap_account_id, is_primary, is_active)
        VALUES (${user.id}, ${user.email}, ${user.email_password}, ${user.jmap_account_id}, true, true)
      `);
      console.log(`  ✓ Migrated email account for user ${user.id}: ${user.email}`);
    }
    console.log('✅ User emails migrated\n');

    // Step 3: Add email_account_id column to contacts (nullable first)
    console.log('Step 3: Adding email_account_id to contacts table...');
    await db.execute(sql`
      ALTER TABLE contacts
      ADD COLUMN IF NOT EXISTS email_account_id uuid
    `);
    console.log('✅ Column added to contacts\n');

    // Step 4: Update existing contacts with email_account_id
    console.log('Step 4: Updating existing contacts with email_account_id...');
    await db.execute(sql`
      UPDATE contacts
      SET email_account_id = (
        SELECT ea.id
        FROM email_accounts ea
        WHERE ea.user_id = contacts.user_id
          AND ea.is_primary = true
        LIMIT 1
      )
      WHERE email_account_id IS NULL
    `);

    const contactsUpdated = await db.execute(sql`
      SELECT COUNT(*) as count FROM contacts WHERE email_account_id IS NOT NULL
    `);
    console.log(`✅ Updated ${contactsUpdated.rows[0].count} contacts\n`);

    // Step 5: Make email_account_id NOT NULL and add foreign key
    console.log('Step 5: Adding constraints to contacts...');
    await db.execute(sql`
      ALTER TABLE contacts
      ALTER COLUMN email_account_id SET NOT NULL
    `);

    await db.execute(sql`
      ALTER TABLE contacts
      ADD CONSTRAINT "contacts_email_account_id_email_accounts_id_fk"
      FOREIGN KEY ("email_account_id") REFERENCES "public"."email_accounts"("id")
      ON DELETE cascade ON UPDATE no action
    `);
    console.log('✅ Constraints added to contacts\n');

    // Step 6: Add email_account_id column to emails (nullable first)
    console.log('Step 6: Adding email_account_id to emails table...');
    await db.execute(sql`
      ALTER TABLE emails
      ADD COLUMN IF NOT EXISTS email_account_id uuid
    `);
    console.log('✅ Column added to emails\n');

    // Step 7: Update existing emails with email_account_id
    console.log('Step 7: Updating existing emails with email_account_id...');
    await db.execute(sql`
      UPDATE emails
      SET email_account_id = (
        SELECT ea.id
        FROM email_accounts ea
        WHERE ea.user_id = emails.user_id
          AND ea.is_primary = true
        LIMIT 1
      )
      WHERE email_account_id IS NULL
    `);

    const emailsUpdated = await db.execute(sql`
      SELECT COUNT(*) as count FROM emails WHERE email_account_id IS NOT NULL
    `);
    console.log(`✅ Updated ${emailsUpdated.rows[0].count} emails\n`);

    // Step 8: Make email_account_id NOT NULL and add foreign key
    console.log('Step 8: Adding constraints to emails...');
    await db.execute(sql`
      ALTER TABLE emails
      ALTER COLUMN email_account_id SET NOT NULL
    `);

    await db.execute(sql`
      ALTER TABLE emails
      ADD CONSTRAINT "emails_email_account_id_email_accounts_id_fk"
      FOREIGN KEY ("email_account_id") REFERENCES "public"."email_accounts"("id")
      ON DELETE cascade ON UPDATE no action
    `);
    console.log('✅ Constraints added to emails\n');

    console.log('🎉 Migration completed successfully!\n');
    console.log('Summary:');
    console.log(`  - Email accounts created: ${usersWithEmail.rows.length}`);
    console.log(`  - Contacts updated: ${contactsUpdated.rows[0].count}`);
    console.log(`  - Emails updated: ${emailsUpdated.rows[0].count}`);

  } catch (error) {
    console.error('❌ Migration failed:', error);
    throw error;
  } finally {
    await pool.end();
  }
}

// Run migration
migrateToEmailAccounts().catch((error) => {
  console.error('Fatal error:', error);
  process.exit(1);
});
