import Database from 'better-sqlite3';
import { drizzle as sqliteDrizzle } from 'drizzle-orm/better-sqlite3';
import { drizzle as postgresDrizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { words, examples, tags, wordTags, seeAlso } from '../src/lib/db/schema';
import 'dotenv/config';

const connectionString = process.env.DATABASE_URL || '';

if (!connectionString) {
  console.error('DATABASE_URL environment variable is required');
  process.exit(1);
}

async function migrate() {
  console.log('Starting SQLite to PostgreSQL migration...\n');

  // Connect to SQLite
  const sqlite = new Database('./data.db');
  const sqliteDb = sqliteDrizzle(sqlite);

  // Connect to PostgreSQL
  const pgClient = postgres(connectionString);
  const pgDb = postgresDrizzle(pgClient, { schema: { words, examples, tags, wordTags, seeAlso } });

  try {
    // Migrate tags first
    console.log('Migrating tags...');
    const sqliteTags = sqlite.prepare('SELECT * FROM tags').all() as any[];

    for (const tag of sqliteTags) {
      await pgDb.insert(tags).values({
        name: tag.name,
        description: tag.description,
      });
    }
    console.log(`✅ Migrated ${sqliteTags.length} tags\n`);

    // Get tag ID mapping (SQLite ID -> PostgreSQL ID)
    const pgTags = await pgDb.select().from(tags);
    const tagIdMap = new Map<number, number>();
    for (let i = 0; i < sqliteTags.length; i++) {
      const sqliteTag = sqliteTags[i];
      const pgTag = pgTags.find(t => t.name === sqliteTag.name);
      if (pgTag) {
        tagIdMap.set(sqliteTag.id, pgTag.id);
      }
    }

    // Migrate words
    console.log('Migrating words...');
    const sqliteWords = sqlite.prepare('SELECT * FROM words').all() as any[];

    for (const word of sqliteWords) {
      const [insertedWord] = await pgDb.insert(words).values({
        hindi: word.hindi,
        english: word.english,
        type: word.type,
        gender: word.gender,
        note: word.note,
      }).returning();

      // Migrate word_tags associations
      const wordTagsData = sqlite.prepare('SELECT * FROM word_tags WHERE word_id = ?').all(word.id) as any[];
      for (const wt of wordTagsData) {
        const newTagId = tagIdMap.get(wt.tag_id);
        if (newTagId) {
          await pgDb.insert(wordTags).values({
            wordId: insertedWord.id,
            tagId: newTagId,
          });
        }
      }

      // Migrate examples
      const examplesData = sqlite.prepare('SELECT * FROM examples WHERE word_id = ?').all(word.id) as any[];
      for (const example of examplesData) {
        await pgDb.insert(examples).values({
          wordId: insertedWord.id,
          hindi: example.hindi,
          english: example.english,
          note: example.note,
        });
      }

      // Migrate see_also
      const seeAlsoData = sqlite.prepare('SELECT * FROM see_also WHERE word_id = ?').all(word.id) as any[];
      for (const sa of seeAlsoData) {
        await pgDb.insert(seeAlso).values({
          wordId: insertedWord.id,
          reference: sa.reference,
          note: sa.note,
        });
      }
    }
    console.log(`✅ Migrated ${sqliteWords.length} words with all relations\n`);

    console.log('Migration complete! 🎉');

  } catch (error) {
    console.error('Migration failed:', error);
    process.exit(1);
  } finally {
    sqlite.close();
    await pgClient.end();
  }
}

migrate();
