/**
 * ============================================================
 * SCRIPT DE MIGRAÇÃO: SUPABASE CLOUD → POSTGRESQL LOCAL
 * ============================================================
 * 
 * COMO USAR:
 *   1. Certifique-se de que o PostgreSQL local está rodando (docker-compose up postgres)
 *   2. Instale as dependências: npm install pg @supabase/supabase-js dotenv
 *   3. Configure as variáveis de ambiente no arquivo .env.migration
 *   4. Execute: npx tsx migrate_to_local.ts
 * 
 * IMPORTANTE:
 *   - Este script NÃO altera nada no Supabase. Ele apenas LÊ.
 *   - Senhas são copiadas EXATAMENTE como estão, sem rehash.
 *   - O script usa transações atômicas: se falhar no meio, nada é salvo.
 */

import { createClient } from '@supabase/supabase-js';
import pg from 'pg';
import fs from 'fs';

// ============================================================
// CONFIGURAÇÃO — Altere aqui ou use .env.migration
// ============================================================
const SUPABASE_URL = process.env.VITE_SUPABASE_URL || 'https://ekbuvcjsfcczviqqlfit.supabase.co';
const SUPABASE_KEY = process.env.VITE_SUPABASE_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImVrYnV2Y2pzZmNjenZpcXFsZml0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzA5OTU0MzIsImV4cCI6MjA4NjU3MTQzMn0.oIzBeGF-PjaviZejYb1TeOOEzMm-Jjth1XzvJrjD6us';
const DATABASE_URL = process.env.DATABASE_URL || 'postgresql://edumanager:EduManager2026!Seguro@150.230.87.131:5432/edumanager';

// ============================================================
// INICIALIZAÇÃO
// ============================================================
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);
const pool = new pg.Pool({ connectionString: DATABASE_URL });

function log(emoji: string, msg: string) {
  console.log(`${emoji}  ${msg}`);
}

function logCount(table: string, count: number) {
  log('📦', `${table}: ${count} registro(s) migrado(s)`);
}

// ============================================================
// FUNÇÕES DE MIGRAÇÃO POR ENTIDADE
// ============================================================

async function migrateConfiguracoes(client: pg.PoolClient, schoolData: any) {
  const profile = schoolData.profile || {};
  const evoConfig = schoolData.evolutionConfig || {};
  const msgTemplates = schoolData.messageTemplates || {};

  await client.query(`
    INSERT INTO configuracoes (id, nome, endereco, cidade, estado, cep, cnpj, telefone, email, tipo, logo, evolution_api_url, evolution_instance_name, evolution_api_key, message_templates)
    VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
    ON CONFLICT (id) DO UPDATE SET
      nome = EXCLUDED.nome, endereco = EXCLUDED.endereco, cidade = EXCLUDED.cidade,
      estado = EXCLUDED.estado, cep = EXCLUDED.cep, cnpj = EXCLUDED.cnpj,
      telefone = EXCLUDED.telefone, email = EXCLUDED.email, tipo = EXCLUDED.tipo,
      logo = EXCLUDED.logo, evolution_api_url = EXCLUDED.evolution_api_url,
      evolution_instance_name = EXCLUDED.evolution_instance_name,
      evolution_api_key = EXCLUDED.evolution_api_key,
      message_templates = EXCLUDED.message_templates
  `, [
    profile.id || 'main-school',
    profile.name || 'EduManager School',
    profile.address || '',
    profile.city || '',
    profile.state || '',
    profile.zip || '',
    profile.cnpj || '',
    profile.phone || '',
    profile.email || '',
    profile.type || 'matriz',
    schoolData.logo || '',
    evoConfig.apiUrl || null,
    evoConfig.instanceName || null,
    evoConfig.apiKey || null,
    JSON.stringify(msgTemplates)
  ]);
  logCount('configuracoes', 1);
}

async function migrateUsuarios(client: pg.PoolClient, users: any[]) {
  for (const u of users) {
    await client.query(`
      INSERT INTO usuarios (id, username, display_name, photo_url, password, cpf, role)
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      ON CONFLICT (id) DO UPDATE SET
        username = EXCLUDED.username, display_name = EXCLUDED.display_name,
        password = EXCLUDED.password, cpf = EXCLUDED.cpf, role = EXCLUDED.role
    `, [u.id, u.name, u.displayName || null, u.photoURL || null, u.password, u.cpf || '', u.role || 'admin']);
  }
  logCount('usuarios', users.length);
}

async function migrateCursos(client: pg.PoolClient, courses: any[]) {
  for (const c of courses) {
    await client.query(`
      INSERT INTO cursos (id, nome, duracao, duracao_meses, taxa_matricula, mensalidade, descricao, multa_percentual, juros_percentual)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
      ON CONFLICT (id) DO UPDATE SET
        nome = EXCLUDED.nome, duracao = EXCLUDED.duracao, duracao_meses = EXCLUDED.duracao_meses,
        taxa_matricula = EXCLUDED.taxa_matricula, mensalidade = EXCLUDED.mensalidade,
        descricao = EXCLUDED.descricao
    `, [c.id, c.name, c.duration || '', c.durationMonths || 0, c.registrationFee || 0, c.monthlyFee || 0, c.description || '', c.finePercentage || 0, c.interestPercentage || 0]);
  }
  logCount('cursos', courses.length);
}

async function migrateTurmas(client: pg.PoolClient, classes: any[]) {
  for (const c of classes) {
    await client.query(`
      INSERT INTO turmas (id, nome, curso_id, professor, horario, dia_semana, max_alunos, data_inicio, data_fim, horario_inicio_padrao, horario_fim_padrao)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
      ON CONFLICT (id) DO UPDATE SET
        nome = EXCLUDED.nome, curso_id = EXCLUDED.curso_id, professor = EXCLUDED.professor,
        horario = EXCLUDED.horario, dia_semana = EXCLUDED.dia_semana,
        max_alunos = EXCLUDED.max_alunos
    `, [
      c.id, c.name, c.courseId || null, c.teacher || '', c.schedule || '',
      c.scheduleDay || null, c.maxStudents || 30,
      c.startDate || null, c.endDate || null,
      c.defaultStartTime || null, c.defaultEndTime || null
    ]);
  }
  logCount('turmas', classes.length);
}

async function migrateAlunos(client: pg.PoolClient, students: any[]) {
  for (const s of students) {
    await client.query(`
      INSERT INTO alunos (
        id, nome, email, telefone, data_nascimento, cpf, rg, rg_data_emissao,
        nome_responsavel, telefone_responsavel, cpf_responsavel, data_nascimento_responsavel,
        turma_id, status, motivo_cancelamento, data_matricula, foto_url, face_descriptor,
        cep, rua, numero, bairro, cidade, estado,
        desconto, tem_responsavel, modelo_contrato_id,
        numero_matricula, senha_portal
      ) VALUES (
        $1, $2, $3, $4, $5, $6, $7, $8,
        $9, $10, $11, $12,
        $13, $14, $15, $16, $17, $18,
        $19, $20, $21, $22, $23, $24,
        $25, $26, $27,
        $28, $29
      )
      ON CONFLICT (id) DO UPDATE SET
        nome = EXCLUDED.nome, email = EXCLUDED.email, telefone = EXCLUDED.telefone,
        turma_id = EXCLUDED.turma_id, status = EXCLUDED.status,
        numero_matricula = EXCLUDED.numero_matricula, senha_portal = EXCLUDED.senha_portal
    `, [
      s.id, s.name, s.email || '', s.phone || '',
      s.birthDate || null, s.cpf || '', s.rg || null, s.rgIssueDate || null,
      s.guardianName || null, s.guardianPhone || null, s.guardianCpf || null, s.guardianBirthDate || null,
      s.classId || null, s.status || 'active', s.cancellationReason || null,
      s.registrationDate || null,
      // FOTO: Copia a URL (se já migrou para Storage) ou o base64 temporariamente
      s.photo || null,
      // FACE DESCRIPTOR: Array de números para reconhecimento facial
      s.faceDescriptor ? JSON.stringify(s.faceDescriptor) : null,
      s.addressZip || '', s.addressStreet || '', s.addressNumber || '',
      s.addressNeighborhood || '', s.addressCity || '', s.addressState || '',
      s.discount || 0, s.hasGuardian || false, s.contractTemplateId || null,
      // CRÍTICO: Matrícula e Senha copiadas EXATAMENTE como estão
      s.enrollmentNumber || null, s.portalPassword || null
    ]);
  }
  logCount('alunos', students.length);
}

async function migrateAulas(client: pg.PoolClient, lessons: any[]) {
  for (const l of lessons) {
    await client.query(`
      INSERT INTO aulas (id, turma_id, data, horario_inicio, horario_fim, status, tipo, motivo_cancelamento, aula_original_id)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
      ON CONFLICT (id) DO UPDATE SET
        status = EXCLUDED.status, horario_inicio = EXCLUDED.horario_inicio,
        horario_fim = EXCLUDED.horario_fim
    `, [
      l.id, l.classId, l.date, l.startTime || null, l.endTime || null,
      l.status || 'scheduled', l.type || 'regular',
      l.cancelReason || null, l.originalLessonId || null
    ]);
  }
  logCount('aulas', lessons.length);
}

async function migrateFrequencias(client: pg.PoolClient, attendance: any[]) {
  for (const a of attendance) {
    await client.query(`
      INSERT INTO frequencias (id, aluno_id, turma_id, data, foto, verificado, tipo, justificativa, justificativa_aceita)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
      ON CONFLICT (id) DO UPDATE SET
        tipo = EXCLUDED.tipo, justificativa = EXCLUDED.justificativa,
        justificativa_aceita = EXCLUDED.justificativa_aceita
    `, [
      a.id, a.studentId, a.classId, a.date,
      a.photo || null, a.verified || false,
      a.type || 'presence', a.justification || null, a.justificationAccepted ?? null
    ]);
  }
  logCount('frequencias', attendance.length);
}

async function migrateDisciplinas(client: pg.PoolClient, subjects: any[]) {
  for (const s of subjects) {
    await client.query(`
      INSERT INTO disciplinas (id, nome, turma_id)
      VALUES ($1, $2, $3)
      ON CONFLICT (id) DO UPDATE SET nome = EXCLUDED.nome
    `, [s.id, s.name, s.classId || null]);
  }
  logCount('disciplinas', subjects.length);
}

async function migratePeriodos(client: pg.PoolClient, periods: any[]) {
  for (const p of periods) {
    await client.query(`
      INSERT INTO periodos (id, nome)
      VALUES ($1, $2)
      ON CONFLICT (id) DO UPDATE SET nome = EXCLUDED.nome
    `, [p.id, p.name]);
  }
  logCount('periodos', periods.length);
}

async function migrateNotas(client: pg.PoolClient, grades: any[]) {
  for (const g of grades) {
    await client.query(`
      INSERT INTO notas (id, aluno_id, disciplina_id, valor, periodo)
      VALUES ($1, $2, $3, $4, $5)
      ON CONFLICT (id) DO UPDATE SET valor = EXCLUDED.valor
    `, [g.id, g.studentId, g.subjectId, g.value || 0, g.period]);
  }
  logCount('notas', grades.length);
}

async function migratePagamentos(client: pg.PoolClient, payments: any[]) {
  for (const p of payments) {
    await client.query(`
      INSERT INTO pagamentos (
        id, aluno_id, contrato_id, valor, desconto, tipo_desconto, multa, juros,
        vencimento, status, data_pagamento, tipo, numero_parcela, total_parcelas,
        descricao, asaas_payment_id, asaas_payment_url, installment_id
      ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18)
      ON CONFLICT (id) DO UPDATE SET status = EXCLUDED.status, data_pagamento = EXCLUDED.data_pagamento
    `, [
      p.id, p.studentId, p.contractId || null, p.amount, p.discount || 0,
      p.discountType || null, p.lateFee || 0, p.interest || 0,
      p.dueDate, p.status || 'pending', p.paidDate || null,
      p.type || 'monthly', p.installmentNumber || null, p.totalInstallments || null,
      p.description || null, p.asaasPaymentId || null, p.asaasPaymentUrl || null,
      p.installmentId || null
    ]);
  }
  logCount('pagamentos', payments.length);
}

async function migrateContratos(client: pg.PoolClient, contracts: any[]) {
  for (const c of contracts) {
    await client.query(`
      INSERT INTO contratos (id, aluno_id, titulo, conteudo, created_at)
      VALUES ($1, $2, $3, $4, $5)
      ON CONFLICT (id) DO UPDATE SET titulo = EXCLUDED.titulo, conteudo = EXCLUDED.conteudo
    `, [c.id, c.studentId, c.title, c.content, c.createdAt || new Date().toISOString()]);
  }
  logCount('contratos', contracts.length);
}

async function migrateModelosContrato(client: pg.PoolClient, templates: any[]) {
  for (const t of templates) {
    await client.query(`
      INSERT INTO modelos_contrato (id, nome, conteudo)
      VALUES ($1, $2, $3)
      ON CONFLICT (id) DO UPDATE SET nome = EXCLUDED.nome, conteudo = EXCLUDED.conteudo
    `, [t.id, t.name, t.content]);
  }
  logCount('modelos_contrato', templates.length);
}

async function migrateNotificacoes(client: pg.PoolClient, notifications: any[]) {
  for (const n of notifications) {
    await client.query(`
      INSERT INTO notificacoes (id, aluno_id, titulo, mensagem, lida, anexo, created_at)
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      ON CONFLICT (id) DO UPDATE SET lida = EXCLUDED.lida
    `, [n.id, n.studentId, n.title, n.message, n.read || false, n.attachment || null, n.createdAt || new Date().toISOString()]);
  }
  logCount('notificacoes', notifications.length);
}

async function migrateCertificados(client: pg.PoolClient, certificates: any[]) {
  for (const c of certificates) {
    await client.query(`
      INSERT INTO certificados (id, aluno_id, descricao, imagem_frente, imagem_verso, data_emissao, overlays_frente, overlays_verso)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
      ON CONFLICT (id) DO NOTHING
    `, [
      c.id, c.studentId, c.description || null, c.frontImage, c.backImage || null,
      c.issueDate, JSON.stringify(c.frontOverlays || []), JSON.stringify(c.backOverlays || [])
    ]);
  }
  logCount('certificados', certificates.length);
}

async function migrateApostilas(client: pg.PoolClient, handouts: any[]) {
  for (const h of handouts) {
    await client.query(`
      INSERT INTO apostilas (id, nome, preco, descricao, multa_percentual, juros_percentual)
      VALUES ($1, $2, $3, $4, $5, $6)
      ON CONFLICT (id) DO UPDATE SET nome = EXCLUDED.nome, preco = EXCLUDED.preco
    `, [h.id, h.name, h.price || 0, h.description || null, h.finePercentage || 0, h.interestPercentage || 0]);
  }
  logCount('apostilas', handouts.length);
}

async function migrateEntregasApostilas(client: pg.PoolClient, deliveries: any[]) {
  for (const d of deliveries) {
    await client.query(`
      INSERT INTO entregas_apostilas (id, aluno_id, apostila_id, status_entrega, status_pagamento, data_entrega, data_pagamento, asaas_payment_id, asaas_payment_url)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
      ON CONFLICT (id) DO NOTHING
    `, [
      d.id, d.studentId, d.handoutId, d.deliveryStatus || 'pending',
      d.paymentStatus || 'pending', d.deliveryDate || null, d.paymentDate || null,
      d.asaasPaymentId || null, d.asaasPaymentUrl || null
    ]);
  }
  logCount('entregas_apostilas', deliveries.length);
}

async function migrateFuncionarios(client: pg.PoolClient, categories: any[], employees: any[]) {
  for (const c of categories) {
    await client.query(`
      INSERT INTO categorias_funcionarios (id, nome)
      VALUES ($1, $2)
      ON CONFLICT (id) DO UPDATE SET nome = EXCLUDED.nome
    `, [c.id, c.name]);
  }
  logCount('categorias_funcionarios', categories.length);

  for (const e of employees) {
    await client.query(`
      INSERT INTO funcionarios (id, nome, cpf, telefone, email, data_admissao, categoria_id)
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      ON CONFLICT (id) DO UPDATE SET nome = EXCLUDED.nome
    `, [e.id, e.name, e.cpf || '', e.phone || '', e.email || '', e.admissionDate || null, e.categoryId || null]);
  }
  logCount('funcionarios', employees.length);
}

async function migrateProvas(client: pg.PoolClient, exams: any[]) {
  for (const e of exams) {
    await client.query(`
      INSERT INTO provas (id, turma_id, disciplina_id, periodo_id, titulo, duracao_minutos, status)
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      ON CONFLICT (id) DO UPDATE SET titulo = EXCLUDED.titulo, status = EXCLUDED.status
    `, [e.id, e.classId, e.subjectId || null, e.periodId || null, e.title, e.durationMinutes || 60, e.status || 'draft']);

    // Migrar questões da prova
    const questions = e.questions || [];
    for (let i = 0; i < questions.length; i++) {
      const q = questions[i];
      await client.query(`
        INSERT INTO questoes_provas (id, prova_id, texto, imagem_url, opcoes, indice_correto, ordem)
        VALUES ($1, $2, $3, $4, $5, $6, $7)
        ON CONFLICT (id) DO UPDATE SET texto = EXCLUDED.texto, opcoes = EXCLUDED.opcoes
      `, [q.id, e.id, q.text, q.imageUrl || null, JSON.stringify(q.options || []), q.correctOptionIndex || 0, i]);
    }
  }
  logCount('provas + questoes', exams.length);
}

// ============================================================
// MIGRAR TABELAS SEPARADAS DO SUPABASE
// ============================================================

async function migrateCobrancasAsaas(client: pg.PoolClient) {
  log('🔄', 'Buscando tabela alunos_cobrancas do Supabase...');

  const { data, error } = await supabase
    .from('alunos_cobrancas')
    .select('*');

  if (error) {
    log('⚠️', `Erro ao buscar alunos_cobrancas: ${error.message}. Pulando...`);
    return;
  }

  const cobrancas = data || [];
  for (const c of cobrancas) {
    await client.query(`
      INSERT INTO alunos_cobrancas (id, aluno_id, asaas_customer_id, asaas_payment_id, asaas_installment_id, installment, valor, vencimento, status, data_pagamento, link_boleto, link_carne, transaction_receipt_url)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
      ON CONFLICT (id) DO NOTHING
    `, [
      c.id, c.aluno_id, c.asaas_customer_id || null, c.asaas_payment_id || null,
      c.asaas_installment_id || null, c.installment || null,
      c.valor, c.vencimento, c.status || 'PENDENTE', c.data_pagamento || null,
      c.link_boleto || null, c.link_carne || null, c.transaction_receipt_url || null
    ]);
  }
  logCount('alunos_cobrancas', cobrancas.length);
}

async function migrateSubmissoesProvas(client: pg.PoolClient) {
  log('🔄', 'Buscando tabela provas_submissoes do Supabase...');

  const { data, error } = await supabase
    .from('provas_submissoes')
    .select('*');

  if (error) {
    log('⚠️', `Erro ao buscar provas_submissoes: ${error.message}. Pulando...`);
    return;
  }

  const subs = data || [];
  for (const s of subs) {
    await client.query(`
      INSERT INTO provas_submissoes (id, aluno_id, prova_id, total_questoes, acertos, erros, percentual, nota_final, respostas, created_at)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
      ON CONFLICT (id) DO NOTHING
    `, [
      s.id || `sub-${Date.now()}`, s.aluno_id, s.exam_id,
      s.total_questions || 0, s.correct_count || 0, s.wrong_count || 0,
      s.percentage || 0, s.final_score || 0,
      JSON.stringify(s.answers_json || {}), s.created_at || new Date().toISOString()
    ]);
  }
  logCount('provas_submissoes', subs.length);
}

// ============================================================
// BACKUP DO JSON COMPLETO (Segurança)
// ============================================================

async function saveJsonBackup(schoolData: any) {
  const fileName = `backup_supabase_${new Date().toISOString().split('T')[0]}.json`;
  fs.writeFileSync(fileName, JSON.stringify(schoolData, null, 2), 'utf8');
  log('💾', `Backup completo salvo em: ${fileName}`);
}

// ============================================================
// FUNÇÃO PRINCIPAL
// ============================================================

async function main() {
  console.log('');
  console.log('╔══════════════════════════════════════════════════════════╗');
  console.log('║   MIGRAÇÃO EDUMANAGER: SUPABASE → POSTGRESQL LOCAL      ║');
  console.log('╚══════════════════════════════════════════════════════════╝');
  console.log('');

  // 1. Buscar o JSON blob do Supabase
  log('🌐', 'Conectando ao Supabase Cloud...');
  const { data: schoolRow, error: fetchError } = await supabase
    .from('school_data')
    .select('data')
    .eq('id', 1)
    .single();

  if (fetchError || !schoolRow?.data) {
    log('❌', `FALHA AO CONECTAR AO SUPABASE: ${fetchError?.message || 'Dados não encontrados'}`);
    process.exit(1);
  }

  const schoolData = schoolRow.data;
  log('✅', 'Dados baixados do Supabase com sucesso!');

  // 2. Salvar backup local primeiro (segurança)
  await saveJsonBackup(schoolData);

  // 3. Conectar ao PostgreSQL local
  log('🔌', 'Conectando ao PostgreSQL local...');
  const client = await pool.connect();

  try {
    // TRANSAÇÃO ATÔMICA: Tudo ou nada
    await client.query('BEGIN');
    log('🔒', 'Transação iniciada (modo atômico)');

    // 3.5 Criar tabelas se não existirem
    log('🏗️', 'Rodando schema.sql para garantir que as tabelas existem...');
    const schemaSql = fs.readFileSync('../schema.sql', 'utf8');
    await client.query(schemaSql);
    log('✅', 'Tabelas verificadas/criadas no Postgres local!');

    // 4. Também salvar o JSON completo na tabela legada para ponte
    log('📋', 'Salvando JSON blob na tabela school_data (ponte)...');
    await client.query(`
      INSERT INTO school_data (id, data, updated_at)
      VALUES (1, $1, NOW())
      ON CONFLICT (id) DO UPDATE SET data = EXCLUDED.data, updated_at = NOW()
    `, [JSON.stringify(schoolData)]);

    // 5. Migrar entidade por entidade
    console.log('');
    log('🚀', '═══ INICIANDO MIGRAÇÃO TABELA POR TABELA ═══');
    console.log('');

    await migrateConfiguracoes(client, schoolData);
    await migrateUsuarios(client, schoolData.users || []);
    await migrateCursos(client, schoolData.courses || []);
    await migrateTurmas(client, schoolData.classes || []);
    await migrateAlunos(client, schoolData.students || []);
    await migrateAulas(client, schoolData.lessons || []);
    await migrateFrequencias(client, schoolData.attendance || []);
    await migrateDisciplinas(client, schoolData.subjects || []);
    await migratePeriodos(client, schoolData.periods || []);
    await migrateNotas(client, schoolData.grades || []);
    await migratePagamentos(client, schoolData.payments || []);
    await migrateContratos(client, schoolData.contracts || []);
    await migrateModelosContrato(client, schoolData.contractTemplates || []);
    await migrateNotificacoes(client, schoolData.notifications || []);
    await migrateCertificados(client, schoolData.certificates || []);
    await migrateApostilas(client, schoolData.handouts || []);
    await migrateEntregasApostilas(client, schoolData.handoutDeliveries || []);
    await migrateFuncionarios(client, schoolData.employeeCategories || [], schoolData.employees || []);
    await migrateProvas(client, schoolData.exams || []);

    // 6. Migrar tabelas separadas do Supabase
    console.log('');
    log('🔄', '═══ MIGRANDO TABELAS SEPARADAS ═══');
    console.log('');

    await migrateCobrancasAsaas(client);
    await migrateSubmissoesProvas(client);

    // 7. Commit da transação
    await client.query('COMMIT');

    console.log('');
    console.log('╔══════════════════════════════════════════════════════════╗');
    console.log('║   ✅  MIGRAÇÃO CONCLUÍDA COM SUCESSO!                   ║');
    console.log('║                                                          ║');
    console.log('║   • Todos os dados foram copiados com integridade        ║');
    console.log('║   • Senhas mantidas EXATAMENTE como estavam              ║');
    console.log('║   • Backup JSON salvo localmente                         ║');
    console.log('║   • Tabela school_data (legada) populada como ponte      ║');
    console.log('╚══════════════════════════════════════════════════════════╝');
    console.log('');

  } catch (error: any) {
    // ROLLBACK: Se qualquer coisa falhar, NADA é salvo
    await client.query('ROLLBACK');
    console.log('');
    log('❌', '══════════════════════════════════════════════════');
    log('❌', `ERRO NA MIGRAÇÃO: ${error.message}`);
    log('❌', 'ROLLBACK executado. Nenhum dado foi alterado no PostgreSQL.');
    log('❌', '══════════════════════════════════════════════════');
    console.log('');
    console.error(error);
  } finally {
    client.release();
    await pool.end();
  }
}

// Execução
main().catch(console.error);
