import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { z } from 'zod'
import prisma from '@/lib/prisma'
import { authOptions } from '@/lib/auth'
import { generateQris, getQrImageUrl } from '@/lib/cashify'
import { createVipOrder } from '@/lib/vip-reseller'
import { notifyOrderSuccess, notifyAccountDelivery } from '@/lib/notifications'

const orderSchema = z.object({
  productType: z.enum(['VIP', 'DIGITAL']),
  productId: z.string(),
  targetId: z.string().optional(),
  zone: z.string().optional(),
  additionalData: z.string().optional(),
  quantity: z.number().int().positive().default(1),
  paymentMethod: z.enum(['qris', 'balance']).default('qris'),
  voucherCode: z.string().optional(),
})

export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession(authOptions)
    if (!session?.user?.id) {
      return NextResponse.json({ error: 'Silakan login terlebih dahulu' }, { status: 401 })
    }

    const body = await req.json()
    const data = orderSchema.parse(body)

    // Get product & price
    let price = 0
    let productName = ''
    let digitalProduct = null
    let vipProduct = null

    if (data.productType === 'VIP') {
      vipProduct = await prisma.vipProduct.findUnique({
        where: { id: data.productId, isActive: true, status: true },
      })
      if (!vipProduct) return NextResponse.json({ error: 'Produk tidak tersedia' }, { status: 404 })
      if (!data.targetId) return NextResponse.json({ error: 'ID tujuan diperlukan' }, { status: 400 })
      price = Number(vipProduct.sellPrice)
      productName = `${vipProduct.gameName} - ${vipProduct.productName}`
    } else {
      digitalProduct = await prisma.digitalProduct.findUnique({
        where: { id: data.productId, isActive: true },
      })
      if (!digitalProduct) return NextResponse.json({ error: 'Produk tidak tersedia' }, { status: 404 })
      // Only check stock for AUTO delivery — MANUAL products don't need stock
      if (digitalProduct.type === 'AUTO' && digitalProduct.stock < 1) {
        return NextResponse.json({ error: 'Stok habis' }, { status: 400 })
      }
      price = Number(digitalProduct.price)
      productName = digitalProduct.name
    }

    const user = await prisma.user.findUnique({ where: { id: session.user.id } })
    if (!user) return NextResponse.json({ error: 'User tidak ditemukan' }, { status: 404 })

    // Validasi Voucher
    let discountAmount = 0
    let appliedVoucherId = null

    if (data.voucherCode) {
      const voucher = await prisma.voucher.findUnique({
        where: { code: data.voucherCode.toUpperCase() }
      })

      if (!voucher || !voucher.isActive) {
        return NextResponse.json({ error: 'Kode voucher tidak valid' }, { status: 400 })
      }
      if (voucher.maxUses > 0 && voucher.usedCount >= voucher.maxUses) {
        return NextResponse.json({ error: 'Kuota voucher sudah habis' }, { status: 400 })
      }
      if (voucher.expiresAt && new Date() > new Date(voucher.expiresAt)) {
        return NextResponse.json({ error: 'Kode voucher sudah kadaluarsa' }, { status: 400 })
      }

      if (voucher.discountType === 'PERCENTAGE') {
        discountAmount = (price * Number(voucher.discountValue)) / 100
      } else {
        discountAmount = Number(voucher.discountValue)
      }
      if (discountAmount > price) discountAmount = price
      
      appliedVoucherId = voucher.id
    }

    const finalPrice = price - discountAmount;

    // Anti double order check
    const recentOrder = await prisma.order.findFirst({
      where: {
        userId: session.user.id,
        status: 'PENDING',
        createdAt: { gte: new Date(Date.now() - 30000) }, // 30 seconds
        ...(data.productType === 'VIP' ? { vipProductId: data.productId, targetId: data.targetId } : { digitalProductId: data.productId }),
      },
    })
    if (recentOrder) {
      return NextResponse.json({ error: 'Order serupa sedang diproses', orderId: recentOrder.id }, { status: 429 })
    }

    // ============================================
    // BALANCE PAYMENT LOGIC
    // ============================================
    if (data.paymentMethod === 'balance') {
      if (Number(user.balance) < finalPrice) {
        return NextResponse.json({ error: 'Saldo tidak mencukupi' }, { status: 400 })
      }

      // Create Order and deduct balance
      const newBalance = Number(user.balance) - finalPrice
      
      const [order] = await prisma.$transaction([
        prisma.order.create({
          data: {
            userId: session.user.id,
            productType: data.productType,
            vipProductId: data.productType === 'VIP' ? data.productId : null,
            digitalProductId: data.productType === 'DIGITAL' ? data.productId : null,
            targetId: data.targetId,
            zone: data.zone,
            additionalData: data.additionalData,
            quantity: data.quantity,
            price: finalPrice, // Keep the final paid amount
            totalAmount: finalPrice,
            status: 'PAID', // Start as PAID
            paymentMethod: 'balance',
            paidAt: new Date(),
            voucherId: appliedVoucherId,
            discountAmount: discountAmount > 0 ? discountAmount : null,
          },
        }),
        prisma.user.update({
          where: { id: user.id },
          data: { balance: newBalance },
        }),
        prisma.walletTransaction.create({
          data: {
            userId: session.user.id,
            type: 'PAYMENT',
            amount: price,
            balanceBefore: user.balance,
            balanceAfter: newBalance,
            status: 'SUCCESS',
            description: `Pembayaran Order - ${productName}`,
          },
        }),
      ])

      // If there's a voucher, increment the usage count
      if (appliedVoucherId) {
        await prisma.voucher.update({
          where: { id: appliedVoucherId },
          data: { usedCount: { increment: 1 } }
        })
      }

      // Execute fulfillment
      let isFailed = false;

      if (order.productType === 'VIP' && vipProduct) {
        try {
          const vipResult = await createVipOrder({
            service: vipProduct.providerCode,
            dataNo: order.targetId!,
            dataZone: order.zone || undefined,
            additionalData: order.additionalData || undefined,
          })
          await prisma.order.update({
            where: { id: order.id },
            data: { status: 'PROCESSING', vipTrxId: vipResult.trxid },
          })
        } catch (e: any) {
          isFailed = true;
          await prisma.$transaction([
            prisma.order.update({
              where: { id: order.id },
              data: { status: 'FAILED', adminNote: e.message },
            }),
            prisma.user.update({
              where: { id: user.id },
              data: { balance: Number(user.balance) },
            }),
            prisma.walletTransaction.create({
              data: {
                userId: user.id,
                type: 'REFUND',
                amount: price,
                balanceBefore: newBalance,
                balanceAfter: Number(user.balance),
                status: 'SUCCESS',
                description: `Auto Refund - VIP Error: ${e.message.slice(0, 30)}`,
                orderId: order.id,
              },
            }),
          ])
        }
      } else if (order.productType === 'DIGITAL' && digitalProduct) {
        if (digitalProduct.type === 'AUTO') {
          const account = await prisma.productAccount.findFirst({
            where: { productId: digitalProduct.id, status: 'AVAILABLE' },
          })
          if (account) {
            await prisma.$transaction([
              prisma.productAccount.update({
                where: { id: account.id },
                data: { status: 'SOLD', soldAt: new Date(), orderId: order.id },
              }),
              prisma.digitalProduct.update({
                where: { id: digitalProduct.id },
                data: { stock: { decrement: 1 } },
              }),
              prisma.order.update({
                where: { id: order.id },
                data: {
                  status: 'SUCCESS',
                  accountId: account.id,
                  deliveryData: {
                    email: account.email,
                    password: account.password,
                    extra: account.extra
                  },
                  deliveredAt: new Date()
                }
              }),
            ])

            await notifyAccountDelivery(user, {
              name: user.name || '',
              orderId: order.id,
              productName: digitalProduct.name,
              email: account.email,
              password: account.password,
              extra: account.extra || undefined
            })
          } else {
            await prisma.order.update({
              where: { id: order.id },
              data: { status: 'PROCESSING', adminNote: 'Stok AUTO habis, perlu delivery manual' },
            })
          }
        } else {
          // MANUAL delivery - set to PROCESSING, admin will fulfill manually
          await prisma.order.update({
            where: { id: order.id },
            data: { status: 'PROCESSING' },
          })
        }
      }

      if (!isFailed) {
        await notifyOrderSuccess(user, {
          name: user.name,
          orderId: order.id,
          productName,
          targetId: order.targetId || undefined,
          zone: order.zone || undefined,
          price,
          isManual: digitalProduct?.type === 'MANUAL',
        })
      }

      return NextResponse.json({
        order: {
          id: order.id,
          productName,
          price,
          totalAmount: price,
          status: 'SUCCESS', // To skip QRIS logic on frontend
          paymentMethod: 'balance',
        },
      })
    }

    // ============================================
    // QRIS PAYMENT LOGIC
    // ============================================
    const qris = await generateQris({
      amount: finalPrice,
      expiredInMinutes: 15,
      useUniqueCode: true,
    })

    const order = await prisma.order.create({
      data: {
        userId: session.user.id,
        productType: data.productType,
        vipProductId: data.productType === 'VIP' ? data.productId : null,
        digitalProductId: data.productType === 'DIGITAL' ? data.productId : null,
        targetId: data.targetId,
        zone: data.zone,
        additionalData: data.additionalData,
        quantity: data.quantity,
        price: finalPrice,
        totalAmount: qris.totalAmount,
        status: 'PENDING',
        invoiceId: qris.transactionId,
        paymentMethod: 'qris',
        voucherId: appliedVoucherId,
        discountAmount: discountAmount > 0 ? discountAmount : null,
      },
    })

    await prisma.paymentInvoice.create({
      data: {
        transactionId: qris.transactionId,
        type: 'ORDER_PAYMENT',
        userId: session.user.id,
        orderId: order.id,
        amount: finalPrice,
        totalAmount: qris.totalAmount,
        uniqueCode: qris.uniqueNominal,
        qrString: qris.qr_string,
        status: 'pending',
        packageIds: JSON.stringify(qris.packageIds),
        expiredAt: new Date(Date.now() + 15 * 60 * 1000),
      },
    })

    const qrImageUrl = getQrImageUrl(qris.qr_string)

    return NextResponse.json({
      order: {
        id: order.id,
        productName,
        price,
        totalAmount: qris.totalAmount,
        uniqueCode: qris.uniqueNominal,
        status: order.status,
        invoiceId: qris.transactionId,
        qrString: qris.qr_string,
        qrImageUrl,
        expiresAt: new Date(Date.now() + 15 * 60 * 1000).toISOString(),
        paymentMethod: 'qris',
      },
    })
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json({ error: error.errors[0].message }, { status: 400 })
    }
    console.error('[ORDER CREATE]', error)
    return NextResponse.json({ error: error instanceof Error ? error.message : 'Gagal membuat order' }, { status: 500 })
  }
}

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

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

    const [orders, total] = await Promise.all([
      prisma.order.findMany({
        where: {
          userId: session.user.id,
          ...(status && { status: status as any }),
        },
        include: {
          vipProduct: { select: { gameName: true, productName: true } },
          digitalProduct: { select: { name: true, thumbnail: true } },
          review: { select: { id: true, rating: true } },
        },
        orderBy: { createdAt: 'desc' },
        skip,
        take: limit,
      }),
      prisma.order.count({
        where: { userId: session.user.id, ...(status && { status: status as any }) },
      }),
    ])

    // Auto-heal stuck processing VIP orders
    const processingVipOrders = orders.filter(o => o.status === 'PROCESSING' && o.productType === 'VIP' && o.vipTrxId)
    if (processingVipOrders.length > 0) {
      try {
        const { checkVipOrderStatus } = await import('@/lib/vip-reseller')
        for (const order of processingVipOrders) {
          try {
            const vipStatusObj = await checkVipOrderStatus(order.vipTrxId!)
            const mappedStatus = String(vipStatusObj.status).toLowerCase()
            
            let newStatus = order.status
            if (mappedStatus === 'success') newStatus = 'SUCCESS'
            else if (mappedStatus === 'error' || mappedStatus === 'failed') newStatus = 'FAILED'
            
            if (newStatus !== order.status) {
              if (newStatus === 'FAILED') {
                const orderUser = await prisma.user.findUnique({ where: { id: order.userId } })
                if (orderUser) {
                  const newBalance = Number(orderUser.balance) + Number(order.price)
                  await prisma.$transaction([
                    prisma.order.update({
                      where: { id: order.id },
                      data: { status: 'FAILED' }
                    }),
                    prisma.user.update({
                      where: { id: orderUser.id },
                      data: { balance: newBalance }
                    }),
                    prisma.walletTransaction.create({
                      data: {
                        userId: orderUser.id,
                        type: 'REFUND',
                        amount: order.price,
                        balanceBefore: orderUser.balance,
                        balanceAfter: newBalance,
                        status: 'SUCCESS',
                        description: `Auto Refund - VIP Error`,
                        orderId: order.id
                      }
                    })
                  ])
                }
              } else {
                await prisma.order.update({
                  where: { id: order.id },
                  data: {
                    status: newStatus as any,
                    ...(newStatus === 'SUCCESS' ? { deliveredAt: new Date() } : {})
                  }
                })
              }
              // Update in memory so the returned response reflects it immediately
              order.status = newStatus as any
            }
          } catch (err) {
            console.error(`[AUTO-HEAL VIP] Failed for order ${order.id}`, err)
          }
        }
      } catch (err) {
        console.error('[AUTO-HEAL VIP] Module error', err)
      }
    }

    return NextResponse.json({ orders, total, page, limit, pages: Math.ceil(total / limit) })
  } catch (error) {
    console.error('[ORDERS GET]', error)
    return NextResponse.json({ error: 'Gagal memuat order' }, { status: 500 })
  }
}
