const pg = require('pg');
const { S3Client, ListBucketsCommand, ListObjectsV2Command } = require('@aws-sdk/client-s3');

const DATABASE_URL = process.env.DATABASE_URL || 'postgresql://edumanager:EduManager2026!Seguro@postgres:5432/edumanager';
const pool = new pg.Pool({ connectionString: DATABASE_URL });

const MINIO_ENDPOINT = process.env.MINIO_ENDPOINT || 'minio';
const MINIO_PORT = process.env.MINIO_PORT || '9000';
const MINIO_ACCESS_KEY = process.env.MINIO_ACCESS_KEY || 'minioadmin';
const MINIO_SECRET_KEY = process.env.MINIO_SECRET_KEY || 'MiniO2026!Seguro';

const s3Client = new S3Client({
  endpoint: `http://${MINIO_ENDPOINT}:${MINIO_PORT}`,
  region: 'us-east-1',
  credentials: {
    accessKeyId: MINIO_ACCESS_KEY,
    secretAccessKey: MINIO_SECRET_KEY,
  },
  forcePathStyle: true,
});

async function main() {
  try {
    console.log('--- 1. BUSCANDO TODAS AS TABELAS E DADOS DO POSTGRESQL ---');
    const { rows: tables } = await pool.query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'");
    console.log(`Encontradas ${tables.length} tabelas no banco de dados.`);
    
    let dbContentDump = '';
    for (const t of tables) {
      const tableName = t.table_name;
      try {
        const { rows } = await pool.query(`SELECT * FROM "${tableName}"`);
        dbContentDump += JSON.stringify(rows) + ' ';
      } catch (err) {
        console.warn(`Aviso: não foi possível ler a tabela ${tableName}:`, err.message);
      }
    }
    console.log(`Dumping de referências concluído (${(dbContentDump.length / 1024 / 1024).toFixed(2)} MB).`);
    
    console.log('\n--- 2. LISTANDO ARQUIVOS NO STORAGE MINIO ---');
    const bucketsData = await s3Client.send(new ListBucketsCommand({}));
    const buckets = bucketsData.Buckets || [];
    console.log(`Encontrados ${buckets.length} buckets no MinIO.`);
    
    const allFiles = [];
    let totalStorageSize = 0;
    
    for (const bucket of buckets) {
      try {
        const objects = await s3Client.send(new ListObjectsV2Command({ Bucket: bucket.Name }));
        const contents = objects.Contents || [];
        console.log(`Bucket [${bucket.Name}]: ${contents.length} arquivos encontrados.`);
        for (const obj of contents) {
          totalStorageSize += obj.Size || 0;
          allFiles.push({
            bucket: bucket.Name,
            key: obj.Key,
            size: obj.Size || 0,
            url: `/storage/${bucket.Name}/${obj.Key}`
          });
        }
      } catch (err) {
        console.warn(`Não foi possível listar objetos do bucket ${bucket.Name}:`, err.message);
      }
    }
    console.log(`Total geral no MinIO: ${(totalStorageSize / 1024 / 1024).toFixed(2)} MB (${allFiles.length} arquivos).`);
    
    console.log('\n--- 3. FILTRANDO ARQUIVOS NÃO UTILIZADOS ---');
    const unusedFiles = [];
    const usedFiles = [];
    
    for (const file of allFiles) {
      const hasReference = dbContentDump.includes(file.key) || dbContentDump.includes(file.url);
      if (hasReference) {
        usedFiles.push(file);
      } else {
        unusedFiles.push(file);
      }
    }
    
    const totalUnusedSize = unusedFiles.reduce((acc, curr) => acc + curr.size, 0);
    console.log(`\nRESULTADOS:`);
    console.log(`- Arquivos em Uso: ${usedFiles.length}`);
    console.log(`- Arquivos Órfãos (NÃO usados): ${unusedFiles.length}`);
    console.log(`- Espaço sendo desperdiçado: ${(totalUnusedSize / 1024 / 1024).toFixed(2)} MB`);
    
    if (unusedFiles.length > 0) {
      console.log('\n--- LISTA DE ARQUIVOS NÃO UTILIZADOS ---');
      unusedFiles.forEach((file, index) => {
        console.log(`${index + 1}. Bucket: [${file.bucket}] | Arquivo: ${file.key} | Tamanho: ${(file.size / 1024).toFixed(2)} KB`);
      });
    } else {
      console.log('\nExcelente! Todos os arquivos armazenados no MinIO estão sendo referenciados no banco de dados!');
    }
  } catch (error) {
    console.error('Erro na execução:', error);
  } finally {
    await pool.end();
  }
}
main();
