import { type NextRequest, NextResponse } from "next/server"
import { createAdminClient } from "@/lib/supabase/admin"
import Stripe from "stripe"
// TODO: Add type for cart item
interface CartItem {
  id: string
  name?: string
  type?: string
  price?: number
  quantity?: number
  // Shortened keys for minimal cart data
  p?: number // price
  q?: number // quantity
  t?: string // type: "t" for ticket, "m" for menu_item
  i?: Array<{ m?: string; q?: number; menu_item_id?: string; quantity?: number }> // ticket_inclusions (simplified)
  quantity_sold?: number
  ticket_inclusions?: Array<{
    menu_item_id: string
    quantity: number
  }>
}

function normalizeCartItem(item: CartItem): {
  id: string
  name: string
  type: string
  price: number
  quantity: number
  ticket_inclusions?: Array<{ menu_item_id: string; quantity: number }>
} {
  let normalizedInclusions: Array<{ menu_item_id: string; quantity: number }> | undefined

  if (item.ticket_inclusions) {
    normalizedInclusions = item.ticket_inclusions
  } else if (item.i && item.i.length > 0) {
    normalizedInclusions = item.i.map((inc) => ({
      menu_item_id: inc.m || inc.menu_item_id || "",
      quantity: inc.q ?? inc.quantity ?? 1,
    }))
  }

  return {
    id: item.id,
    name: item.name || "",
    type: item.type || (item.t === "t" ? "ticket" : item.t === "m" ? "menu_item" : "unknown"),
    price: item.price ?? item.p ?? 0,
    quantity: item.quantity ?? item.q ?? 1,
    ticket_inclusions: normalizedInclusions,
  }
}

function getCartDataFromMetadata(metadata: Record<string, string>): string | null {
  // Check if cart data is in a single field
  if (metadata.cartData) {
    return metadata.cartData
  }

  // Check if cart data is split into chunks
  const chunkCount = metadata.cartDataChunks ? Number.parseInt(metadata.cartDataChunks, 10) : 0
  if (chunkCount > 0) {
    let cartData = ""
    for (let i = 0; i < chunkCount; i++) {
      const chunk = metadata[`cartData${i}`]
      if (chunk) {
        cartData += chunk
      }
    }
    return cartData || null
  }

  return null
}

export async function POST(request: NextRequest) {
  try {
    const { sessionId, eventId } = await request.json()

    if (!sessionId || !eventId) {
      return NextResponse.json({ error: "Missing sessionId or eventId" }, { status: 400 })
    }

    const supabase = createAdminClient()
    const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: "2025-04-30.basil" })

    // Check if order already exists for this session
    const { data: existingOrder } = await supabase
      .from("orders")
      .select("id, checkout_type")
      .eq("payment_intent_id", sessionId)
      .maybeSingle()

    if (existingOrder) {
      const { data: existingChits } = await supabase
        .from("chits")
        .select("id")
        .eq("order_id", existingOrder.id)
        .limit(1)

      if (!existingChits || existingChits.length === 0) {
        console.log("[v0] Order exists but no chits found, processing items...")

        const session = await stripe.checkout.sessions.retrieve(sessionId)
        const metadata = (session.metadata || {}) as Record<string, string>

        let cartItems: CartItem[] = []
        const cartDataJson = getCartDataFromMetadata(metadata)
        if (cartDataJson) {
          try {
            cartItems = JSON.parse(cartDataJson)
            console.log("[v0] Parsed cart items:", cartItems)
          } catch {
            console.log("[v0] Failed to parse cartData")
          }
        }

        if (cartItems.length > 0) {
          const normalizedItems = cartItems.map(normalizeCartItem)
          await processOrderItems(supabase, existingOrder.id, eventId, normalizedItems)
        }
      }

      return NextResponse.json({
        orderId: existingOrder.id,
        checkoutType: existingOrder.checkout_type || "registered",
      })
    }

    // Fetch session from Stripe
    let session: Stripe.Checkout.Session
    try {
      session = await stripe.checkout.sessions.retrieve(sessionId)
    } catch {
      return NextResponse.json({ error: "Could not retrieve payment session" }, { status: 400 })
    }

    if (session.payment_status !== "paid") {
      return NextResponse.json({ error: `Payment not completed: ${session.payment_status}` }, { status: 400 })
    }

    const metadata = (session.metadata || {}) as Record<string, string>
    const checkoutType = metadata.checkoutType || "registered"

    let cartItems: CartItem[] = []
    const cartDataJson = getCartDataFromMetadata(metadata)
    if (cartDataJson) {
      try {
        cartItems = JSON.parse(cartDataJson)
        console.log("[v0] Parsed cart items for new order:", cartItems)
      } catch {
        console.log("[v0] Failed to parse cartData for new order")
      }
    }

    if (cartItems.length === 0) {
      return NextResponse.json(
        {
          error: "Payment successful but order details not found. Check your email or contact support.",
        },
        { status: 400 },
      )
    }

    const normalizedItems = cartItems.map(normalizeCartItem)

    const customerEmail = metadata.customerEmail || session.customer_email || ""
    const customerName = metadata.customerName || customerEmail.split("@")[0] || "Customer"

    // Create the order with checkout_type
    const { data: order, error: orderError } = await supabase
      .from("orders")
      .insert({
        event_id: eventId,
        customer_name: customerName,
        customer_email: customerEmail,
        customer_phone: metadata.customerPhone || null,
        table_number: metadata.tableNumber || null,
        total_amount: metadata.total ? Number.parseFloat(metadata.total) : (session.amount_total || 0) / 100,
        tax_amount: metadata.taxAmount ? Number.parseFloat(metadata.taxAmount) : 0,
        payment_status: "completed",
        payment_intent_id: sessionId,
        checkout_type: checkoutType,
      })
      .select()
      .single()

    if (orderError) {
      return NextResponse.json({ error: `Order creation failed: ${orderError.message}` }, { status: 500 })
    }

    // Process chits and tickets with normalized items
    await processOrderItems(supabase, order.id, eventId, normalizedItems)

    // Send confirmation email (non-blocking - order succeeds even if email fails)
    try {
      console.log("[CHECKOUT] 📧 Attempting to send confirmation email to:", customerEmail)
      console.log("[CHECKOUT] Order ID:", order.id, "Event ID:", eventId)
      
      // Import and call the email function directly (more reliable than HTTP fetch)
      const { sendOrderEmail } = await import("@/lib/email/send-order-email")
      const emailResult = await sendOrderEmail(order.id, eventId)
      
      if (emailResult.success) {
        console.log("[CHECKOUT] ✅ Confirmation email sent successfully!")
        console.log("[CHECKOUT] Email ID:", emailResult.emailId)
        console.log("[CHECKOUT] Recipient:", customerEmail)
      } else {
        console.error("[CHECKOUT] ❌ Failed to send confirmation email:", emailResult.message)
      }
    } catch (emailError: any) {
      console.error("[CHECKOUT] ❌ Exception while sending confirmation email")
      console.error("[CHECKOUT] Error message:", emailError?.message || emailError)
      console.error("[CHECKOUT] Error stack:", emailError?.stack)
      // Don't fail the order if email fails - order is already created successfully
    }

    return NextResponse.json({
      orderId: order.id,
      checkoutType: checkoutType,
    })
  } catch (error: any) {
    console.error("[v0] Checkout process error:", error)
    return NextResponse.json({ error: error.message || "Internal server error" }, { status: 500 })
  }
}

async function processOrderItems(supabase: any, orderId: string, eventId: string, cartItems: any[]) {
  console.log("[v0] Processing order items. Total items:", cartItems.length)
  console.log(
    "[v0] Cart items with types:",
    cartItems.map((i) => ({ name: i.name, type: i.type })),
  )

  const menuItems = cartItems.filter((item) => item.type === "menu_item")
  const ticketItems = cartItems.filter((item) => item.type === "ticket")

  console.log("[v0] Menu items:", menuItems.length, "Ticket items:", ticketItems.length)

  for (const item of cartItems) {
    if (!item.name) {
      if (item.type === "ticket") {
        const { data: ticket } = await supabase.from("event_tickets").select("name").eq("id", item.id).single()
        if (ticket) item.name = ticket.name
      } else if (item.type === "menu_item") {
        const { data: menuItem } = await supabase.from("menu_items").select("name").eq("id", item.id).single()
        if (menuItem) item.name = menuItem.name
      }
    }
  }

  // Create chits for menu items
  const chits: any[] = menuItems.flatMap((item) =>
    Array.from({ length: item.quantity }, (_, index) => ({
      order_id: orderId,
      event_id: eventId,
      menu_item_id: item.id,
      item_name: item.name,
      quantity: 1,
      price: item.price,
      qr_code_data: `${orderId}-${item.id}-${Date.now()}-${index}`,
      fulfillment_status: "pending",
    })),
  )

  // Process ticket inclusions
  for (const ticket of ticketItems) {
    if (ticket.ticket_inclusions && ticket.ticket_inclusions.length > 0) {
      for (let i = 0; i < ticket.quantity; i++) {
        for (const inclusion of ticket.ticket_inclusions) {
          const { data: menuItem } = await supabase
            .from("menu_items")
            .select("id, name, price")
            .eq("id", inclusion.menu_item_id)
            .single()

          if (menuItem) {
            for (let q = 0; q < inclusion.quantity; q++) {
              chits.push({
                order_id: orderId,
                event_id: eventId,
                menu_item_id: menuItem.id,
                item_name: menuItem.name,
                quantity: 1,
                price: 0,
                qr_code_data: `inclusion-${orderId}-${ticket.id}-${menuItem.id}-${Date.now()}-${i}-${q}`,
                fulfillment_status: "pending",
              })
            }
          }
        }
      }
    }
  }

  console.log("[v0] Total chits to insert:", chits.length)

  if (chits.length > 0) {
    const { error: chitsError } = await supabase.from("chits").insert(chits)
    if (chitsError) {
      console.error("[v0] Error inserting chits:", chitsError)
    } else {
      console.log("[v0] Chits inserted successfully")
    }
  }

  // Create order_tickets
  const orderTickets = ticketItems.flatMap((ticket) =>
    Array.from({ length: ticket.quantity }, (_, index) => ({
      order_id: orderId,
      event_id: eventId,
      ticket_id: ticket.id,
      ticket_name: ticket.name,
      price: ticket.price,
      quantity: 1,
      qr_code_data: `ticket-${orderId}-${ticket.id}-${Date.now()}-${index}`,
      fulfillment_status: "pending",
    })),
  )

  console.log("[v0] Total order_tickets to insert:", orderTickets.length)

  if (orderTickets.length > 0) {
    const { error: ticketsError } = await supabase.from("order_tickets").insert(orderTickets)
    if (ticketsError) {
      console.error("[v0] Error inserting order_tickets:", ticketsError)
    } else {
      console.log("[v0] Order tickets inserted successfully")
    }

    // Update ticket quantities sold
    for (const ticket of ticketItems) {
      const { data: currentTicket } = await supabase
        .from("event_tickets")
        .select("quantity_sold")
        .eq("id", ticket.id)
        .single()

      await supabase
        .from("event_tickets")
        .update({ quantity_sold: (currentTicket?.quantity_sold || 0) + ticket.quantity })
        .eq("id", ticket.id)
    }
  }
}
