import { Client } from 'pg';
import * as dotenv from 'dotenv';
import { readFileSync } from 'fs';
import { join } from 'path';

// Load environment variables
dotenv.config({ path: '.env' });

async function checkAndCreateDatabases() {
  // Get connection info from DATABASE_URL or use defaults
  const mainDbUrl = process.env.DATABASE_URL || 'postgresql://postgres@localhost:5432/postgres';
  const authDbUrl = process.env.DATABASE_URL_AUTH || 'postgresql://postgres@localhost:5432/postgres';
  
  // Parse connection strings to get connection details
  const parseUrl = (url: string) => {
    const match = url.match(/postgresql:\/\/([^:]+):([^@]+)@([^:]+):(\d+)\/(.+)/) ||
                   url.match(/postgresql:\/\/([^@]+)@([^:]+):(\d+)\/(.+)/) ||
                   url.match(/postgresql:\/\/([^@]+)@([^:]+)\/(.+)/);
    
    if (match) {
      if (match.length === 6) {
        // With password
        return {
          user: match[1],
          password: match[2],
          host: match[3],
          port: parseInt(match[4]),
          database: match[5],
        };
      } else if (match.length === 5) {
        // Without password, with port
        return {
          user: match[1],
          host: match[2],
          port: parseInt(match[3]),
          database: match[4],
        };
      } else if (match.length === 4) {
        // Without password, without port
        return {
          user: match[1],
          host: match[2],
          port: 5432,
          database: match[3],
        };
      }
    }
    
    // Fallback to defaults
    return {
      user: 'postgres',
      host: 'localhost',
      port: 5432,
      database: 'postgres',
    };
  };

  const mainConfig = parseUrl(mainDbUrl);
  const authConfig = parseUrl(authDbUrl);
  
  // Connect to postgres database to check/create databases
  const adminClient = new Client({
    user: mainConfig.user,
    password: (mainConfig as any).password,
    host: mainConfig.host,
    port: mainConfig.port,
    database: 'postgres', // Connect to postgres database to create other databases
  });

  try {
    console.log('🔍 Checking databases...\n');
    await adminClient.connect();
    console.log('✅ Connected to PostgreSQL\n');

    // Check if punimtag database exists
    const mainDbCheck = await adminClient.query(
      "SELECT 1 FROM pg_database WHERE datname = 'punimtag'"
    );
    
    if (mainDbCheck.rows.length === 0) {
      console.log('⚠️  punimtag database does not exist');
      console.log('   This is the main database with photos - it should already exist.');
      console.log('   If you need to create it, please do so manually or ensure your PunimTag setup is complete.\n');
    } else {
      console.log('✅ punimtag database exists\n');
    }

    // Check if punimtag_auth database exists
    const authDbCheck = await adminClient.query(
      "SELECT 1 FROM pg_database WHERE datname = 'punimtag_auth'"
    );

    if (authDbCheck.rows.length === 0) {
      console.log('📦 Creating punimtag_auth database...');
      await adminClient.query('CREATE DATABASE punimtag_auth');
      console.log('✅ punimtag_auth database created\n');
    } else {
      console.log('✅ punimtag_auth database exists\n');
    }

    await adminClient.end();

    // Now connect to punimtag_auth and create tables
    const authClient = new Client({
      user: authConfig.user,
      password: (authConfig as any).password,
      host: authConfig.host,
      port: authConfig.port,
      database: 'punimtag_auth',
    });

    try {
      await authClient.connect();
      console.log('🔗 Connected to punimtag_auth database\n');

      // Check if users table exists
      const usersTableCheck = await authClient.query(`
        SELECT EXISTS (
          SELECT FROM information_schema.tables 
          WHERE table_schema = 'public' 
          AND table_name = 'users'
        );
      `);

      if (!usersTableCheck.rows[0].exists) {
        console.log('📋 Creating tables in punimtag_auth...');
        
        // Read and execute setup-auth-tables.sql
        const setupScript = readFileSync(
          join(__dirname, '../setup-auth-tables.sql'),
          'utf-8'
        );
        
        // Split by semicolons and execute each statement
        const statements = setupScript
          .split(';')
          .map(s => s.trim())
          .filter(s => s.length > 0 && !s.startsWith('--') && !s.startsWith('\\'));

        for (const statement of statements) {
          if (statement.length > 0) {
            try {
              await authClient.query(statement);
            } catch (error: any) {
              // Ignore "already exists" errors
              if (!error.message.includes('already exists')) {
                console.error(`Error executing: ${statement.substring(0, 50)}...`);
                throw error;
              }
            }
          }
        }

        console.log('✅ Tables created\n');
      } else {
        console.log('✅ Tables already exist in punimtag_auth\n');
      }

      // Check for required migrations
      console.log('🔍 Checking for required migrations...\n');
      
      // Check pending_photos table
      const pendingPhotosCheck = await authClient.query(`
        SELECT EXISTS (
          SELECT FROM information_schema.tables 
          WHERE table_schema = 'public' 
          AND table_name = 'pending_photos'
        );
      `);

      if (!pendingPhotosCheck.rows[0].exists) {
        console.log('📋 Creating pending_photos table...');
        const migrationScript = readFileSync(
          join(__dirname, '../migrations/add-pending-photos-table.sql'),
          'utf-8'
        );
        const statements = migrationScript
          .split(';')
          .map(s => s.trim())
          .filter(s => s.length > 0 && !s.startsWith('--') && !s.startsWith('\\'));

        for (const statement of statements) {
          if (statement.length > 0) {
            try {
              await authClient.query(statement);
            } catch (error: any) {
              if (!error.message.includes('already exists')) {
                throw error;
              }
            }
          }
        }
        console.log('✅ pending_photos table created\n');
      }

      // Check email verification columns
      const emailVerificationCheck = await authClient.query(`
        SELECT column_name 
        FROM information_schema.columns 
        WHERE table_schema = 'public' 
        AND table_name = 'users' 
        AND column_name = 'email_verified'
      `);

      if (emailVerificationCheck.rows.length === 0) {
        console.log('📋 Adding email verification columns...');
        const migrationScript = readFileSync(
          join(__dirname, '../migrations/add-email-verification-columns.sql'),
          'utf-8'
        );
        const statements = migrationScript
          .split(';')
          .map(s => s.trim())
          .filter(s => s.length > 0 && !s.startsWith('--') && !s.startsWith('\\'));

        for (const statement of statements) {
          if (statement.length > 0) {
            try {
              await authClient.query(statement);
            } catch (error: any) {
              if (!error.message.includes('already exists')) {
                throw error;
              }
            }
          }
        }
        console.log('✅ Email verification columns added\n');
      }

      console.log('🎉 Database setup complete!\n');
      console.log('Next steps:');
      console.log('1. Ensure your .env file has correct DATABASE_URL_AUTH');
      console.log('2. Run: npm run prisma:generate:all');
      console.log('3. Create admin user: npx tsx scripts/create-admin-user.ts');

    } catch (error: any) {
      console.error('\n❌ Error setting up tables:', error.message);
      if (error.message.includes('permission denied')) {
        console.error('\n⚠️  Permission denied. You may need to run this as a PostgreSQL superuser.');
      }
      throw error;
    } finally {
      await authClient.end();
    }

  } catch (error: any) {
    console.error('\n❌ Error:', error.message);
    if (error.message.includes('password authentication failed')) {
      console.error('\n⚠️  Authentication failed. Please check:');
      console.error('  1. Database credentials in .env file');
      console.error('  2. PostgreSQL is running');
      console.error('  3. User has permission to create databases');
    }
    process.exit(1);
  } finally {
    await adminClient.end();
  }
}

checkAndCreateDatabases();

