import { NextRequest, NextResponse } from 'next/server'

export const dynamic = 'force-dynamic'
import { db } from '@/lib/db'
import { writeFile, mkdir } from 'fs/promises'
import { existsSync } from 'fs'
import path from 'path'
import { exec } from 'child_process'
import { promisify } from 'util'

const execAsync = promisify(exec)

// This endpoint receives a PDF upload, extracts text, and uses pattern matching
// to identify products, then updates the catalog automatically.
export async function POST(req: NextRequest) {
  try {
    const formData = await req.formData()
    const file = formData.get('pdf') as File

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

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

    // Save uploaded PDF
    const uploadDir = '/home/z/my-project/upload'
    if (!existsSync(uploadDir)) await mkdir(uploadDir, { recursive: true })
    const filePath = path.join(uploadDir, `import-${Date.now()}.pdf`)
    await writeFile(filePath, buffer)

    // Extract text from PDF using pdf skill
    const PDF_SKILL_DIR = '/home/z/my-project/skills/pdf'
    let extractedText = ''

    try {
      const { stdout } = await execAsync(
        `python3 "${PDF_SKILL_DIR}/scripts/pdf.py" extract.text "${filePath}"`,
        { maxBuffer: 50 * 1024 * 1024 }
      )
      const data = JSON.parse(stdout.trim())
      if (data.data && data.data.pages) {
        extractedText = data.data.pages.map((p: any) => p.text).join('\n')
      }
    } catch (e) {
      console.error('PDF extraction error:', e)
    }

    if (!extractedText) {
      return NextResponse.json(
        { status: 'error', message: 'Não foi possível extrair texto do PDF' },
        { status: 500 }
      )
    }

    // Parse products using pattern matching
    // Pattern: (CODE) N.Description ... R$ XX,XX or de R$ XX por R$ XX
    const productsFound: any[] = []

    // Match product patterns like (1234) Description - Volume
    const productPattern = /\((\d{3,5})\)\s*\d*\.?\s*([^\n\r()]{8,120}?)\s*[-–]\s*(\d+[.,]?\d*\s*(?:ml|g|kg|un|comprimidos|x\d))/gi
    let match
    while ((match = productPattern.exec(extractedText)) !== null) {
      const [, code, name, volume] = match
      const cleanName = name.trim().replace(/\s+/g, ' ')

      // Find price near this match
      const afterText = extractedText.substring(match.index, match.index + 500)
      const promoPriceMatch = afterText.match(/por\s*(\d{1,3})\s*,?\s*(\d{2})/i)
      const normalPriceMatch = afterText.match(/de\s*R\$\s*(\d{1,3})[,.]?(\d{2})/i)
      const simplePriceMatch = afterText.match(/R\$\s*(\d{1,3})[,.]?(\d{2})/i)

      let promotionalPrice: number | null = null
      let price: number | null = null

      if (normalPriceMatch) {
        price = parseFloat(`${normalPriceMatch[1]}.${normalPriceMatch[2]}`)
      }
      if (promoPriceMatch) {
        promotionalPrice = parseFloat(`${promoPriceMatch[1]}.${promoPriceMatch[2]}`)
      }
      if (!price && simplePriceMatch) {
        price = parseFloat(`${simplePriceMatch[1]}.${simplePriceMatch[2]}`)
      }
      if (!price && promotionalPrice) price = promotionalPrice * 1.4 // estimate

      let discountPercent: number | null = null
      if (price && promotionalPrice && price > promotionalPrice) {
        discountPercent = Math.round((1 - promotionalPrice / price) * 100)
      }

      // Find page number (approximate by text position)
      const beforeText = extractedText.substring(0, match.index)
      const pageMarkers = beforeText.match(/===== PAGE \d+ =====/g)
      const approxPage = pageMarkers ? pageMarkers.length : 1

      // Detect flags
      const contextWindow = extractedText.substring(
        Math.max(0, match.index - 300),
        Math.min(extractedText.length, match.index + 500)
      )
      const isLaunch = /LANÇAMENTO/i.test(contextWindow)
      const isLowerPriceYear = /MENOR PREÇO\s*DO ANO/i.test(contextWindow)
      const isBestseller = /best.?seller|mais vendido/i.test(contextWindow)

      // Detect category by keywords
      let categorySlug = 'corpo'
      const lowerName = cleanName.toLowerCase()
      if (/unha|esmalte|cutícula|base|smalte/i.test(lowerName)) categorySlug = 'maquiagem'
      else if (/batom|lip|olho|kájal|kajal|máscara.*cílio|pó compacto|maquiagem/i.test(lowerName)) categorySlug = 'maquiagem'
      else if (/shampoo|condicionador|cabelo|capilar|capilar|cílio/i.test(lowerName)) categorySlug = 'cabelos'
      else if (/perfume|fragrância|colônia|eau de toilette/i.test(lowerName)) categorySlug = 'perfumaria'
      else if (/íntimo|intimament|vaginal|menstrual|depil/i.test(lowerName)) categorySlug = 'intimidade'
      else if (/baby|infantil|doce infância|criança|bebê/i.test(lowerName)) categorySlug = 'infantil'
      else if (/aromatizante|difusor|ambiente|casa/i.test(lowerName)) categorySlug = 'casa'
      else if (/suplemento|vitamina|colágeno|comprimido/i.test(lowerName)) categorySlug = 'suplementos'
      else if (/solar|protetor|bronz|fps|pós-sol/i.test(lowerName)) categorySlug = 'corpo'
      else if (/pé|pé|calo|rachadura|dermopés/i.test(lowerName)) categorySlug = 'corpo'
      else if (/desodorante|talco/i.test(lowerName)) categorySlug = 'uso-diario'
      else if (/acne|ruga|sérum|facial|clareador|rosativ|pele/i.test(lowerName)) categorySlug = 'pele'

      productsFound.push({
        code,
        name: cleanName,
        volume: volume.trim(),
        price: price || 0,
        promotionalPrice,
        discountPercent,
        page: approxPage,
        isLaunch,
        isLowerPriceYear,
        isBestseller,
        categorySlug,
      })
    }

    // Deduplicate by code
    const seen = new Set()
    const uniqueProducts = productsFound.filter(p => {
      if (seen.has(p.code)) return false
      seen.add(p.code)
      return true
    })

    // Update database: upsert products
    const categories = await db.category.findMany()
    const catMap = new Map(categories.map(c => [c.slug, c.id]))

    let inserted = 0
    let updated = 0

    for (const p of uniqueProducts) {
      const categoryId = catMap.get(p.categorySlug)
      if (!categoryId) continue

      const slug = p.name.toLowerCase()
        .normalize('NFD').replace(/[\u0300-\u036f]/g, '')
        .replace(/[^a-z0-9\s-]/g, '').trim()
        .replace(/\s+/g, '-').replace(/-+/g, '-')

      try {
        const existing = await db.product.findUnique({ where: { code: p.code } })
        if (existing) {
          await db.product.update({
            where: { code: p.code },
            data: {
              name: p.name,
              price: p.price,
              promotionalPrice: p.promotionalPrice || null,
              discountPercent: p.discountPercent || null,
              page: p.page,
              isLaunch: p.isLaunch,
              isLowerPriceYear: p.isLowerPriceYear,
              categoryId,
            },
          })
          updated++
        } else {
          await db.product.create({
            data: {
              name: p.name,
              code: p.code,
              slug,
              volume: p.volume,
              price: p.price,
              promotionalPrice: p.promotionalPrice || null,
              discountPercent: p.discountPercent || null,
              page: p.page,
              isLaunch: p.isLaunch,
              isLowerPriceYear: p.isLowerPriceYear,
              categoryId,
            },
          })
          inserted++
        }
      } catch (e) {
        // skip duplicates
      }
    }

    // Log import
    await db.importLog.create({
      data: {
        fileName: file.name,
        status: 'success',
        productsFound: uniqueProducts.length,
        message: `${inserted} novos, ${updated} atualizados`,
      },
    })

    return NextResponse.json({
      status: 'success',
      data: {
        fileName: file.name,
        productsFound: uniqueProducts.length,
        inserted,
        updated,
        extractedTextLength: extractedText.length,
      },
    })
  } catch (error) {
    console.error('Import error:', error)
    return NextResponse.json(
      { status: 'error', message: 'Erro ao importar PDF' },
      { status: 500 }
    )
  }
}
