import { NextRequest, NextResponse } from "next/server"
import { createAdminClient } from "@/lib/supabase/admin"
import jwt from "jsonwebtoken"
import fs from "fs"
import path from "path"

/**
 * Generate Google Wallet save URL for order tickets
 * Returns a JWT-signed URL that opens Google Wallet
 */
export async function POST(request: NextRequest) {
  try {
    const { orderId, eventId } = await request.json()

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

    const supabase = createAdminClient()

    // Fetch order with tickets
    const { data: order, error: orderError } = await supabase
      .from("orders")
      .select(
        "*, order_tickets(*), events(name, location, event_date, end_date, end_time, currency, start_time)"
      )
      .eq("id", orderId)
      .eq("event_id", eventId)
      .single()

    if (orderError || !order) {
      return NextResponse.json({ error: "Order not found" }, { status: 404 })
    }

    const event = order.events
    const tickets = order.order_tickets?.filter((t: any) => t.fulfillment_status === "pending") || []

    if (tickets.length === 0) {
      return NextResponse.json({ error: "No available tickets found" }, { status: 404 })
    }

    // Prepare ticket data for Google Wallet
    const ticketData = tickets.map((ticket: any) => ({
      ticket_id: ticket.id,
      email: order.customer_email,
      ticket_holder_name: order.customer_name,
      barcode_value: ticket.qr_code_data,
      event_name: event.name,
      event_date: event.event_date ? new Date(event.event_date).toISOString().split("T")[0] : null,
      event_time: event.start_time || null,
      venue: event.location || "Event Venue",
      ticket_name: ticket.ticket_name,
      ticket_number: ticket.qr_code_data,
    }))

    // Generate Google Wallet URL
    const walletUrl = await generateGoogleWalletUrl(ticketData, event)

    return NextResponse.json({
      url: walletUrl,
      orderId: order.id,
      ticketCount: tickets.length,
      tickets: tickets.map((ticket: any) => ({
        id: ticket.id,
        ticket_name: ticket.ticket_name,
        qr_code: ticket.qr_code_data,
      })),
    })
  } catch (error: any) {
    console.error("[WALLET] Google Wallet generation error:", error)
    return NextResponse.json({ error: error.message || "Failed to generate Google Wallet URL" }, { status: 500 })
  }
}

/**
 * Generate unique object ID for multiple tickets per user
 */
function generateUniqueObjectId(email: string, ticketId: string, issuerId: string): string {
  const uniqueIdentifier = `${email}_${ticketId}`
  const objectSuffix = uniqueIdentifier.replace(/[^\w.-]/gi, "_")
  return `${issuerId}.${objectSuffix}`
}

/**
 * Generate Google Wallet save URL using JWT
 */
async function generateGoogleWalletUrl(ticketData: any[], event: any): Promise<string> {
  // Check if Google Wallet credentials are configured
  const issuerId = process.env.GOOGLE_WALLET_ISSUER_ID
  const serviceAccountEmail = process.env.GOOGLE_WALLET_SERVICE_ACCOUNT_EMAIL
  const privateKey = process.env.GOOGLE_WALLET_PRIVATE_KEY
  const serviceAccountPath = process.env.GOOGLE_WALLET_SERVICE_ACCOUNT_PATH

  if (!issuerId || !serviceAccountEmail) {
    throw new Error(
      "Google Wallet credentials not configured. Please set GOOGLE_WALLET_ISSUER_ID and GOOGLE_WALLET_SERVICE_ACCOUNT_EMAIL environment variables."
    )
  }

  // Try to get private key from env or service account file
  let privateKeyToUse = privateKey

  if (!privateKeyToUse && serviceAccountPath) {
    try {
      const serviceAccountFile = path.join(process.cwd(), serviceAccountPath)
      if (fs.existsSync(serviceAccountFile)) {
        const serviceAccount = JSON.parse(fs.readFileSync(serviceAccountFile, "utf8"))
        privateKeyToUse = serviceAccount.private_key
        if (!serviceAccountEmail || serviceAccountEmail === "your-service@project.iam.gserviceaccount.com") {
          // Use email from service account if not set in env
          const emailFromFile = serviceAccount.client_email
          if (emailFromFile) {
            // Note: We can't modify process.env here, but we can use the email from file
            // For now, we'll use the email from the file if available
          }
        }
      }
    } catch (error) {
      console.error("[WALLET] Error reading service account file:", error)
    }
  }

  if (!privateKeyToUse) {
    throw new Error(
      "Google Wallet private key not found. Please set GOOGLE_WALLET_PRIVATE_KEY environment variable or ensure GOOGLE_WALLET_SERVICE_ACCOUNT_PATH points to a valid service account file."
    )
  }

  // Get the actual service account email (from env or file)
  let actualServiceAccountEmail = serviceAccountEmail
  if (serviceAccountPath && serviceAccountEmail === "your-service@project.iam.gserviceaccount.com") {
    try {
      const serviceAccountFile = path.join(process.cwd(), serviceAccountPath)
      if (fs.existsSync(serviceAccountFile)) {
        const serviceAccount = JSON.parse(fs.readFileSync(serviceAccountFile, "utf8"))
        actualServiceAccountEmail = serviceAccount.client_email || serviceAccountEmail
      }
    } catch (error) {
      // Use the env value if file read fails
    }
  }

  const classSuffix = "TIKKETSPASS"
  const classId = `${issuerId}.${classSuffix}`
  const email = ticketData[0]?.email || "guest@example.com"

  // Create class definition (only once for all tickets)
  const eventTicketClass = {
    id: classId,
    issuerName: "Tikkets",
    reviewStatus: "UNDER_REVIEW",
    eventName: {
      defaultValue: {
        language: "en-US",
        value: ticketData[0]?.event_name || event?.name || "Event Ticket",
      },
    },
  }

  // Create multiple ticket objects
  const eventTicketObjects = ticketData.map((ticket) => {
    const ticketId = ticket.ticket_id || String(Date.now())
    const objectId = generateUniqueObjectId(email, ticketId, issuerId)

    return {
      id: objectId,
      classId: classId,
      state: "ACTIVE",
      barcode: {
        type: "QR_CODE",
        value: ticket.barcode_value || ticket.qr_code_data || "TICKET-ABC123",
      },
      ticketHolderName: ticket.ticket_holder_name || "Guest User",
      ticketNumber: ticket.ticket_number || ticket.barcode_value || "TICKET-ABC123",
      eventName: {
        defaultValue: {
          language: "en-US",
          value: ticket.event_name || "Event Ticket",
        },
      },
      venueName: {
        defaultValue: {
          language: "en-US",
          value: ticket.venue || "Event Venue",
        },
      },
      dateTime: {
        start: {
          date: ticket.event_date || new Date().toISOString().split("T")[0],
        },
      },
      textModulesData: [
        {
          header: "Ticket Type",
          body: ticket.ticket_name || "General Admission",
          id: "TICKET_TYPE",
        },
        {
          header: "Ticket Number",
          body: ticket.ticket_number || ticket.barcode_value || "N/A",
          id: "TICKET_NUMBER",
        },
      ],
    }
  })

  // Create the JWT claims
  const claims = {
    iss: actualServiceAccountEmail,
    aud: "google",
    origins: [process.env.NEXT_PUBLIC_APP_URL?.replace(/^https?:\/\//, "") || "www.tikkets.com"],
    typ: "savetowallet",
    payload: {
      eventTicketClasses: [eventTicketClass],
      eventTicketObjects: eventTicketObjects,
    },
  }

  // Sign the JWT
  // Remove quotes from private key if they exist
  const cleanPrivateKey = privateKeyToUse.replace(/^["']|["']$/g, "").replace(/\\n/g, "\n")

  const token = jwt.sign(claims, cleanPrivateKey, {
    algorithm: "RS256",
  })

  return `https://pay.google.com/gp/v/save/${token}`
}
