export const config = { api: { bodyParser: false } };
export const maxDuration = 120;
export const dynamic = "force-dynamic";
import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
import { uploadFile, buildKey } from '@/lib/spaces'
import OpenAI from 'openai'
import pdfParse from "pdf-parse/lib/pdf-parse.js"


const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

const SYSTEM_PROMPT = `Você é um jurista especialista em Direito brasileiro com amplo conhecimento da legislação vigente.
Analise o processo/documento jurídico a seguir e forneça um parecer completo e detalhado.

Sua análise DEVE incluir:

## 1. Resumo do Processo
Breve resumo dos fatos, partes envolvidas e objeto da ação.

## 2. Tipo de Ação e Rito Processual
Identifique o tipo de ação, o rito processual aplicável e a competência.

## 3. Análise dos Fundamentos Jurídicos
Analise os fundamentos de direito apresentados, verificando:
- Adequação legal
- Citações de artigos de lei
- Jurisprudência aplicável

## 4. Pontos Fortes
Identifique os argumentos mais sólidos e bem fundamentados.

## 5. Pontos Fracos e Vulnerabilidades
Identifique falhas, lacunas ou argumentos frágeis que podem ser explorados pela parte contrária.

## 6. Legislação Aplicável Atualizada
Liste TODA a legislação relevante com artigos específicos:
- Constituição Federal de 1988
- Códigos (CPC, CC, CLT, CDC, CP, CTN, etc.)
- Leis especiais aplicáveis
- Súmulas vinculantes e súmulas do STJ/STF relevantes

## 7. Jurisprudência Relevante
Cite decisões recentes dos tribunais superiores (STF, STJ, TST) e tribunais estaduais que se aplicam ao caso.

## 8. Parecer e Recomendações
Apresente seu parecer sobre:
- Chances de êxito (alta/média/baixa)
- Estratégia processual recomendada
- Providências urgentes, se houver
- Recursos cabíveis
- Prazos importantes a observar

## 9. Conclusão
Síntese final com recomendação objetiva.

Use linguagem técnica jurídica. Cite artigos de lei sempre que possível. Base sua análise na legislação brasileira vigente em 2025/2026.`

const CREDIT_COST = 5

export async function GET(req: NextRequest) {
  const session = await getServerSession(authOptions)
  if (!session?.user?.id) {
    return NextResponse.json({ error: 'Não autorizado' }, { status: 401 })
  }

  const analyses = await prisma.processAnalysis.findMany({
    where: { userId: session.user.id },
    orderBy: { createdAt: 'desc' },
    select: {
      id: true,
      title: true,
      filename: true,
      fileSize: true,
      status: true,
      summary: true,
      createdAt: true,
    },
  })

  return NextResponse.json({ analyses })
}

export async function POST(req: NextRequest) {
  const session = await getServerSession(authOptions)
  if (!session?.user?.id) {
    return NextResponse.json({ error: 'Não autorizado' }, { status: 401 })
  }

  // Check credits
  const user = await prisma.user.findUnique({ where: { id: session.user.id } })
  if (!user || user.credits < CREDIT_COST) {
    return NextResponse.json(
      { error: `Créditos insuficientes. A análise de processo custa ${CREDIT_COST} créditos.` },
      { status: 403 }
    )
  }

  try {
    const formData = await req.formData()
    const file = formData.get('file') as File | null

    if (!file) {
      return NextResponse.json({ error: 'Nenhum arquivo enviado' }, { status: 400 })
    }

    if (file.type !== 'application/pdf') {
      return NextResponse.json({ error: 'Apenas arquivos PDF são aceitos' }, { status: 400 })
    }

    if (file.size > 50 * 1024 * 1024) {
      return NextResponse.json({ error: 'Arquivo muito grande. Máximo: 50MB' }, { status: 400 })
    }

    const buffer = Buffer.from(await file.arrayBuffer())

    // Extract text from PDF
    let extractedText: string
    try {
      const pdfData = await pdfParse(buffer)
      extractedText = pdfData.text
    } catch (pdfErr) {
      console.error('PDF parse error:', pdfErr)
      return NextResponse.json({ error: 'Erro ao ler o PDF. Verifique se o arquivo não está corrompido.' }, { status: 400 })
    }

    if (!extractedText || extractedText.trim().length < 50) {
      return NextResponse.json(
        { error: 'Não foi possível extrair texto suficiente do PDF. O arquivo pode ser uma imagem digitalizada.' },
        { status: 400 }
      )
    }

    // Upload PDF to Spaces
    const key = buildKey(session.user.id, file.name)
    await uploadFile(buffer, key, 'application/pdf')

    // Truncate if needed
    let textForAnalysis = extractedText
    let truncated = false
    if (textForAnalysis.length > 15000) {
      textForAnalysis = textForAnalysis.substring(0, 15000)
      truncated = true
    }

    const title = file.name.replace(/\.pdf$/i, '')

    // Create record
    const analysis = await prisma.processAnalysis.create({
      data: {
        userId: session.user.id,
        title,
        filename: file.name,
        fileKey: key,
        fileSize: file.size,
        extractedText,
        analysis: '',
        status: 'ANALYZING',
      },
    })

    // Deduct credits
    await prisma.user.update({
      where: { id: session.user.id },
      data: { credits: { decrement: CREDIT_COST } },
    })

    // Build user message
    let userMessage = `Analise o seguinte processo/documento jurídico:\n\n${textForAnalysis}`
    if (truncated) {
      userMessage += '\n\n[NOTA: O documento foi truncado para os primeiros 15.000 caracteres devido ao tamanho. A análise pode não cobrir todo o conteúdo.]'
    }

    // Stream response using SSE
    const encoder = new TextEncoder()
    let fullAnalysis = ''

    const stream = new ReadableStream({
      async start(controller) {
        try {
          const completion = await openai.chat.completions.create({
            model: 'gpt-4o-mini',
            messages: [
              { role: 'system', content: SYSTEM_PROMPT },
              { role: 'user', content: userMessage },
            ],
            temperature: 0.3,
            max_tokens: 8000,
            stream: true,
          })

          // Send the analysis ID first
          controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'id', id: analysis.id })}\n\n`))

          for await (const chunk of completion) {
            const content = chunk.choices[0]?.delta?.content
            if (content) {
              fullAnalysis += content
              controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'chunk', content })}\n\n`))
            }
          }

          // Generate summary from first paragraph of analysis
          const summaryMatch = fullAnalysis.match(/## 1\. Resumo do Processo\n+([\s\S]*?)(?=\n## |\n#|$)/)
          const summary = summaryMatch
            ? summaryMatch[1].trim().substring(0, 500)
            : fullAnalysis.substring(0, 300)

          // Save completed analysis
          await prisma.processAnalysis.update({
            where: { id: analysis.id },
            data: {
              analysis: fullAnalysis,
              summary,
              status: 'DONE',
            },
          })

          controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'done', id: analysis.id })}\n\n`))
          controller.close()
        } catch (err) {
          console.error('OpenAI streaming error:', err)

          // Refund credits on error
          await prisma.user.update({
            where: { id: session.user.id },
            data: { credits: { increment: CREDIT_COST } },
          })

          await prisma.processAnalysis.update({
            where: { id: analysis.id },
            data: { status: 'ERROR', analysis: fullAnalysis || 'Erro durante a análise.' },
          })

          controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'error', message: 'Erro ao gerar análise' })}\n\n`))
          controller.close()
        }
      },
    })

    return new NextResponse(stream, {
      headers: {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        Connection: 'keep-alive',
      },
    })
  } catch (error) {
    console.error('Process analysis error:', error)
    return NextResponse.json({ error: 'Erro interno ao processar análise' }, { status: 500 })
  }
}
