// MUST load environment variables BEFORE any other imports
require('dotenv').config({ path: require('path').resolve(__dirname, '../.env.local') });

import { Client } from 'pg';
import admin from 'firebase-admin';
import { FieldValue } from 'firebase-admin/firestore';

const PG_CONNECTION_STRING = 'postgresql://postgres:jhsRNOIyjjVfrdvDXnUVcXXXsuzjvcFc@metro.proxy.rlwy.net:30866/railway';

// Initialize Firebase Admin directly
if (!admin.apps.length) {
  const privateKey = process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, '\n');
  
  if (!process.env.FIREBASE_PROJECT_ID || !process.env.FIREBASE_CLIENT_EMAIL || !privateKey) {
    throw new Error('Missing Firebase Admin credentials. Check your .env.local file.');
  }
  
  admin.initializeApp({
    credential: admin.credential.cert({
      projectId: process.env.FIREBASE_PROJECT_ID,
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
      privateKey: privateKey,
    }),
  });
  
  console.log('✅ Firebase Admin initialized successfully');
}

const adminDb = admin.firestore();
const adminAuth = admin.auth();

interface PgUser {
  id: number;
  email: string;
  name: string;
  created_at: Date;
  settings: any;
}

interface PgProject {
  id: number;
  client_id: number;
  name: string;
  workspace_path: string;
  status: string;
  created_at: Date;
  updated_at: Date;
  metadata: any;
}

interface PgSession {
  id: number;
  session_id: string;
  project_id: number;
  user_id: number;
  started_at: Date;
  last_updated: Date;
  ended_at: Date | null;
  status: string;
  conversation: any[];
  file_changes: any[];
  message_count: number;
  user_message_count: number;
  assistant_message_count: number;
  file_change_count: number;
  duration_minutes: number;
  summary: string | null;
  tasks_identified: any[];
  decisions_made: any[];
  technologies_used: any[];
  metadata: any;
  total_tokens: number;
  prompt_tokens: number;
  completion_tokens: number;
  estimated_cost_usd: number;
  model: string;
}

interface PgWorkCompleted {
  id: number;
  project_id: number;
  session_id: number;
  title: string;
  description: string;
  completed_at: Date;
  files_modified: any[];
  lines_added: number;
  lines_removed: number;
  metadata: any;
}

interface PgClient {
  id: number;
  owner_user_id: number;
  name: string;
  email: string | null;
  created_at: Date;
  metadata: any;
}

async function migrateUsers(pgClient: Client, userMapping: Map<number, string>) {
  console.log('\n📋 Migrating Users...');
  const result = await pgClient.query<PgUser>('SELECT * FROM users');
  
  for (const pgUser of result.rows) {
    try {
      // Create Firebase Auth user
      let firebaseUser;
      try {
        firebaseUser = await adminAuth.getUserByEmail(pgUser.email);
        console.log(`  ✅ User already exists: ${pgUser.email}`);
      } catch {
        // User doesn't exist, create them
        firebaseUser = await adminAuth.createUser({
          email: pgUser.email,
          displayName: pgUser.name,
          emailVerified: true,
        });
        console.log(`  ✨ Created Firebase Auth user: ${pgUser.email}`);
      }
      
      // Store mapping
      userMapping.set(pgUser.id, firebaseUser.uid);
      
      // Create user document in Firestore
      const workspace = pgUser.email.split('@')[0].replace(/[^a-z0-9]/gi, '-').toLowerCase();
      await adminDb.collection('users').doc(firebaseUser.uid).set({
        uid: firebaseUser.uid,
        email: pgUser.email,
        displayName: pgUser.name,
        workspace: workspace,
        settings: pgUser.settings || {},
        createdAt: FieldValue.serverTimestamp(),
        updatedAt: FieldValue.serverTimestamp(),
        migratedFrom: 'postgresql',
        originalPgId: pgUser.id,
      });
      
      console.log(`  ✅ Migrated user: ${pgUser.email} → ${firebaseUser.uid}`);
    } catch (error) {
      console.error(`  ❌ Error migrating user ${pgUser.email}:`, error);
    }
  }
}

async function migrateClients(pgClient: Client, userMapping: Map<number, string>) {
  console.log('\n📋 Migrating Clients...');
  const result = await pgClient.query<PgClient>('SELECT * FROM clients');
  
  for (const pgClient of result.rows) {
    const firebaseUserId = userMapping.get(pgClient.owner_user_id);
    if (!firebaseUserId) {
      console.log(`  ⚠️  Skipping client ${pgClient.name} - user not found`);
      continue;
    }
    
    try {
      const clientRef = adminDb.collection('clients').doc();
      await clientRef.set({
        id: clientRef.id,
        ownerId: firebaseUserId,
        name: pgClient.name,
        email: pgClient.email || null,
        createdAt: FieldValue.serverTimestamp(),
        metadata: pgClient.metadata || {},
        migratedFrom: 'postgresql',
        originalPgId: pgClient.id,
      });
      
      console.log(`  ✅ Migrated client: ${pgClient.name}`);
    } catch (error) {
      console.error(`  ❌ Error migrating client ${pgClient.name}:`, error);
    }
  }
}

async function migrateProjects(pgClient: Client, userMapping: Map<number, string>, projectMapping: Map<number, string>) {
  console.log('\n📋 Migrating Projects...');
  const result = await pgClient.query<PgProject>('SELECT * FROM projects');
  
  for (const pgProject of result.rows) {
    try {
      // Get the client to find the owner
      const clientResult = await pgClient.query('SELECT owner_user_id FROM clients WHERE id = $1', [pgProject.client_id]);
      const firebaseUserId = userMapping.get(clientResult.rows[0]?.owner_user_id);
      
      if (!firebaseUserId) {
        console.log(`  ⚠️  Skipping project ${pgProject.name} - user not found`);
        continue;
      }
      
      // Get user's workspace
      const userDoc = await adminDb.collection('users').doc(firebaseUserId).get();
      const workspace = userDoc.data()?.workspace || 'default-workspace';
      
      const projectRef = adminDb.collection('projects').doc();
      await projectRef.set({
        id: projectRef.id,
        name: pgProject.name,
        slug: pgProject.name.toLowerCase().replace(/[^a-z0-9]/g, '-'),
        userId: firebaseUserId,
        workspace: workspace,
        productName: pgProject.name,
        productVision: pgProject.metadata?.vision || null,
        workspacePath: pgProject.workspace_path,
        status: pgProject.status,
        isForClient: true,
        hasLogo: false,
        hasDomain: false,
        hasWebsite: false,
        hasGithub: false,
        hasChatGPT: false,
        createdAt: FieldValue.serverTimestamp(),
        updatedAt: FieldValue.serverTimestamp(),
        metadata: pgProject.metadata || {},
        migratedFrom: 'postgresql',
        originalPgId: pgProject.id,
      });
      
      projectMapping.set(pgProject.id, projectRef.id);
      console.log(`  ✅ Migrated project: ${pgProject.name} → ${projectRef.id}`);
    } catch (error) {
      console.error(`  ❌ Error migrating project ${pgProject.name}:`, error);
    }
  }
}

async function migrateSessions(pgClient: Client, userMapping: Map<number, string>, projectMapping: Map<number, string>) {
  console.log('\n📋 Migrating Sessions...');
  const result = await pgClient.query<PgSession>('SELECT * FROM sessions ORDER BY started_at');
  
  for (const pgSession of result.rows) {
    try {
      const firebaseUserId = userMapping.get(pgSession.user_id);
      const firebaseProjectId = projectMapping.get(pgSession.project_id);
      
      if (!firebaseUserId) {
        console.log(`  ⚠️  Skipping session ${pgSession.session_id} - user not found`);
        continue;
      }
      
      const sessionRef = adminDb.collection('sessions').doc();
      await sessionRef.set({
        id: sessionRef.id,
        userId: firebaseUserId,
        projectId: firebaseProjectId || null,
        
        // Session data
        startTime: pgSession.started_at,
        endTime: pgSession.ended_at || null,
        duration: pgSession.duration_minutes * 60, // Convert to seconds
        
        // Project context
        workspacePath: null, // Not in old schema
        workspaceName: null,
        
        // AI usage
        model: pgSession.model,
        tokensUsed: pgSession.total_tokens,
        promptTokens: pgSession.prompt_tokens,
        completionTokens: pgSession.completion_tokens,
        cost: parseFloat(String(pgSession.estimated_cost_usd)),
        
        // Context
        filesModified: pgSession.file_changes.map((fc: any) => fc.path || fc.file),
        conversationSummary: pgSession.summary || null,
        conversation: pgSession.conversation || [],
        
        // Additional data from old schema
        messageCount: pgSession.message_count,
        userMessageCount: pgSession.user_message_count,
        assistantMessageCount: pgSession.assistant_message_count,
        fileChangeCount: pgSession.file_change_count,
        tasksIdentified: pgSession.tasks_identified || [],
        decisionsMade: pgSession.decisions_made || [],
        technologiesUsed: pgSession.technologies_used || [],
        
        status: pgSession.status,
        metadata: pgSession.metadata || {},
        
        createdAt: pgSession.started_at,
        updatedAt: pgSession.last_updated,
        
        migratedFrom: 'postgresql',
        originalPgId: pgSession.id,
        originalSessionId: pgSession.session_id,
      });
      
      console.log(`  ✅ Migrated session: ${pgSession.session_id}`);
    } catch (error) {
      console.error(`  ❌ Error migrating session ${pgSession.session_id}:`, error);
    }
  }
}

async function migrateWorkCompleted(pgClient: Client, projectMapping: Map<number, string>) {
  console.log('\n📋 Migrating Work Completed...');
  const result = await pgClient.query<PgWorkCompleted>('SELECT * FROM work_completed ORDER BY completed_at');
  
  for (const work of result.rows) {
    try {
      const firebaseProjectId = projectMapping.get(work.project_id);
      
      if (!firebaseProjectId) {
        console.log(`  ⚠️  Skipping work ${work.title} - project not found`);
        continue;
      }
      
      const workRef = adminDb.collection('workCompleted').doc();
      await workRef.set({
        id: workRef.id,
        projectId: firebaseProjectId,
        sessionId: work.session_id ? `pg-session-${work.session_id}` : null,
        title: work.title,
        description: work.description,
        completedAt: work.completed_at,
        filesModified: work.files_modified || [],
        linesAdded: work.lines_added || 0,
        linesRemoved: work.lines_removed || 0,
        metadata: work.metadata || {},
        createdAt: work.completed_at,
        migratedFrom: 'postgresql',
        originalPgId: work.id,
      });
      
      console.log(`  ✅ Migrated work: ${work.title}`);
    } catch (error) {
      console.error(`  ❌ Error migrating work ${work.title}:`, error);
    }
  }
}

async function main() {
  console.log('🚀 Starting PostgreSQL to Firebase migration...\n');
  
  const pgClient = new Client({
    connectionString: PG_CONNECTION_STRING,
  });
  
  try {
    // Connect to PostgreSQL
    console.log('📡 Connecting to PostgreSQL...');
    await pgClient.connect();
    console.log('✅ Connected to PostgreSQL\n');
    
    // Mappings to track old ID -> new ID
    const userMapping = new Map<number, string>();
    const projectMapping = new Map<number, string>();
    
    // Migrate in order (respecting foreign keys)
    await migrateUsers(pgClient, userMapping);
    await migrateClients(pgClient, userMapping);
    await migrateProjects(pgClient, userMapping, projectMapping);
    await migrateSessions(pgClient, userMapping, projectMapping);
    await migrateWorkCompleted(pgClient, projectMapping);
    
    console.log('\n✅ Migration completed successfully!');
    console.log('\n📊 Summary:');
    console.log(`  - Users migrated: ${userMapping.size}`);
    console.log(`  - Projects migrated: ${projectMapping.size}`);
    
  } catch (error) {
    console.error('\n❌ Migration failed:', error);
    throw error;
  } finally {
    await pgClient.end();
    console.log('\n📡 Disconnected from PostgreSQL');
  }
}

// Run migration
main().catch(console.error);

