#!/usr/bin/env npx ts-node

/**
 * Script de Busca Diária de Publicações
 * 
 * Executa busca de publicações em todos os processos ativos de todos os usuários.
 * Pode ser executado via cron ou manualmente.
 * 
 * Uso: npx ts-node scripts/buscar-publicacoes.ts
 * Ou:  node dist/scripts/buscar-publicacoes.js (se compilado)
 */

import { PrismaClient } from '@prisma/client'
import { buscarPublicacoesReais, buscarPublicacoesEmLote, PublicacaoEncontrada } from '../src/lib/diarios-service'

const prisma = new PrismaClient()

interface BuscaStats {
  totalProcessos: number
  processosComNovas: number
  totalPublicacoes: number
  erros: string[]
  inicioEm: Date
  fimEm?: Date
}

async function buscarPublicacoesDiarias(): Promise<BuscaStats> {
  const stats: BuscaStats = {
    totalProcessos: 0,
    processosComNovas: 0,
    totalPublicacoes: 0,
    erros: [],
    inicioEm: new Date(),
  }
  
  console.log('='.repeat(60))
  console.log(`[${new Date().toISOString()}] Iniciando busca diária de publicações`)
  console.log('='.repeat(60))
  
  try {
    // Busca todos os processos ativos
    const processos = await prisma.processoMonitorado.findMany({
      where: { status: 'ATIVO' },
      select: {
        id: true,
        numeroProcesso: true,
        tribunal: true,
        userId: true,
        user: {
          select: { email: true }
        }
      },
    })
    
    stats.totalProcessos = processos.length
    console.log(`\n📋 Total de processos ativos: ${processos.length}`)
    
    if (processos.length === 0) {
      console.log('Nenhum processo ativo encontrado.')
      return stats
    }
    
    // Busca publicações em lote com rate limiting (500ms entre requisições)
    console.log('\n🔍 Buscando publicações nos diários oficiais...\n')
    
    const resultados = await buscarPublicacoesEmLote(
      processos.map(p => ({
        id: p.id,
        numeroProcesso: p.numeroProcesso,
        tribunal: p.tribunal,
      })),
      500 // delay entre requisições
    )
    
    // Processa resultados
    for (const processo of processos) {
      const resultado = resultados.get(processo.id)
      
      if (!resultado) {
        stats.erros.push(`${processo.numeroProcesso}: Sem resultado`)
        continue
      }
      
      if (!resultado.sucesso) {
        stats.erros.push(`${processo.numeroProcesso}: ${resultado.erro}`)
        continue
      }
      
      let novasDoProcesso = 0
      
      for (const pub of resultado.publicacoes) {
        // Verifica duplicata
        const existing = await prisma.publicacao.findFirst({
          where: {
            processoId: processo.id,
            dataPublicacao: {
              gte: new Date(pub.dataPublicacao.toDateString()),
              lt: new Date(new Date(pub.dataPublicacao).setDate(pub.dataPublicacao.getDate() + 1)),
            },
            tipo: pub.tipo,
          },
        })
        
        if (!existing) {
          await prisma.publicacao.create({
            data: {
              processoId: processo.id,
              dataPublicacao: pub.dataPublicacao,
              diario: pub.diario,
              conteudo: pub.conteudo,
              tipo: pub.tipo,
              prazoCalculado: pub.prazoCalculado,
              prazoTipo: pub.prazoTipo,
              visualizado: false,
            },
          })
          novasDoProcesso++
          stats.totalPublicacoes++
        }
      }
      
      if (novasDoProcesso > 0) {
        stats.processosComNovas++
        console.log(`  ✅ ${processo.numeroProcesso}: ${novasDoProcesso} nova(s) publicação(ões)`)
      } else {
        console.log(`  ➖ ${processo.numeroProcesso}: sem novas publicações`)
      }
    }
    
  } catch (error) {
    const msg = error instanceof Error ? error.message : 'Erro desconhecido'
    stats.erros.push(`Erro geral: ${msg}`)
    console.error('\n❌ Erro durante execução:', error)
  } finally {
    await prisma.$disconnect()
  }
  
  stats.fimEm = new Date()
  
  // Resumo final
  console.log('\n' + '='.repeat(60))
  console.log('📊 RESUMO DA BUSCA')
  console.log('='.repeat(60))
  console.log(`Processos verificados: ${stats.totalProcessos}`)
  console.log(`Processos com novas publicações: ${stats.processosComNovas}`)
  console.log(`Total de novas publicações: ${stats.totalPublicacoes}`)
  console.log(`Erros: ${stats.erros.length}`)
  
  if (stats.erros.length > 0) {
    console.log('\n⚠️ Erros encontrados:')
    stats.erros.forEach(e => console.log(`  - ${e}`))
  }
  
  const duracao = ((stats.fimEm.getTime() - stats.inicioEm.getTime()) / 1000).toFixed(1)
  console.log(`\n⏱️ Tempo de execução: ${duracao}s`)
  console.log(`[${stats.fimEm.toISOString()}] Busca finalizada\n`)
  
  return stats
}

// Executar
buscarPublicacoesDiarias()
  .then(stats => {
    process.exit(stats.erros.length > 0 ? 1 : 0)
  })
  .catch(error => {
    console.error('Erro fatal:', error)
    process.exit(1)
  })
