import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import prisma from '@/lib/prisma'
import { authOptions } from '@/lib/auth'
import { getVipServices } from '@/lib/vip-reseller'
import { slugify, calculateSellPrice } from '@/lib/utils'

// GET - List VIP products
export async function GET(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions)
    if (session?.user?.role !== 'ADMIN') {
      return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
    }

    const { searchParams } = new URL(req.url)
    const page = parseInt(searchParams.get('page') || '1')
    const limit = parseInt(searchParams.get('limit') || '20')
    const search = searchParams.get('search') || ''
    const skip = (page - 1) * limit

    const [products, total] = await Promise.all([
      prisma.vipProduct.findMany({
        where: search
          ? {
              OR: [
                { gameName: { contains: search } },
                { productName: { contains: search } },
                { providerCode: { contains: search } },
              ],
            }
          : {},
        include: { category: { select: { name: true } } },
        orderBy: { gameName: 'asc' },
        skip,
        take: limit,
      }),
      prisma.vipProduct.count(),
    ])

    return NextResponse.json({ products, total, page, limit, pages: Math.ceil(total / limit) })
  } catch (error) {
    console.error('[ADMIN VIP PRODUCTS GET]', error)
    return NextResponse.json({ error: 'Gagal memuat produk VIP' }, { status: 500 })
  }
}

// POST - Sync VIP products from provider
export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions)
    if (session?.user?.role !== 'ADMIN') {
      return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
    }

    const { defaultMargin = 10, filterGame } = await req.json()

    const vipProducts = await getVipServices(filterGame)

    // 1. Bulk handle categories
    const uniqueGames = Array.from(new Set(vipProducts.map(p => p.game)))
    const existingCategories = await prisma.gameCategory.findMany()
    const existingSlugs = new Set(existingCategories.map(c => c.slug))
    
    const newCategoriesData = uniqueGames
      .map(game => ({ name: game, slug: slugify(game) }))
      .filter(cat => !existingSlugs.has(cat.slug))

    if (newCategoriesData.length > 0) {
      await prisma.gameCategory.createMany({ data: newCategoriesData })
    }

    // Map slugs to category IDs
    const allCategories = await prisma.gameCategory.findMany()
    const categoryMap = new Map(allCategories.map(c => [c.slug, c.id]))

    // 2. Fetch existing products for update vs create logic
    const existingProducts = await prisma.vipProduct.findMany({ select: { providerCode: true, margin: true } })
    const existingMap = new Map(existingProducts.map(p => [p.providerCode, p.margin]))

    // 3. Prepare updates and creations
    const toCreate = []
    const updatePromises = []
    const processedCodes = new Set()

    for (const product of vipProducts) {
      if (processedCodes.has(product.code)) continue // Skip duplicates from API payload
      processedCodes.add(product.code)
      const slug = slugify(product.game)
      const categoryId = categoryMap.get(slug)
      if (!categoryId) continue

      const basePrice = product.price.premium || product.price.basic
      const sellPrice = calculateSellPrice(basePrice, defaultMargin)

      if (existingMap.has(product.code)) {
        const existingMargin = existingMap.get(product.code) || 0
        updatePromises.push(
          prisma.vipProduct.update({
            where: { providerCode: product.code },
            data: {
              gameName: product.game,
              productName: product.name,
              price: basePrice,
              sellPrice: existingMargin > 0 ? calculateSellPrice(basePrice, Number(existingMargin)) : sellPrice,
              description: product.description,
              status: product.status === 'available',
              categoryId,
              syncedAt: new Date(),
            },
          })
        )
      } else {
        toCreate.push({
          providerCode: product.code,
          gameName: product.game,
          productName: product.name,
          price: basePrice,
          sellPrice,
          margin: defaultMargin,
          description: product.description,
          status: product.status === 'available',
          categoryId,
          syncedAt: new Date(),
        })
      }
    }

    // 4. Execute in bulk
    let created = 0
    let synced = 0

    if (toCreate.length > 0) {
      const createRes = await prisma.vipProduct.createMany({ data: toCreate, skipDuplicates: true })
      created = createRes.count
    }

    if (updatePromises.length > 0) {
      // Chunk updates to prevent transaction too large errors (SQLite limit is usually 999 vars, but we are doing separate queries)
      // Executing concurrently in batches of 100
      for (let i = 0; i < updatePromises.length; i += 100) {
        await Promise.all(updatePromises.slice(i, i + 100))
      }
      synced = updatePromises.length
    }

    return NextResponse.json({
      message: `Sync selesai: ${created} produk baru, ${synced} produk diperbarui`,
      created,
      synced,
      total: vipProducts.length,
    })
  } catch (error) {
    console.error('[VIP SYNC]', error)
    return NextResponse.json({ error: error instanceof Error ? error.message : 'Gagal sync produk VIP' }, { status: 500 })
  }
}
