import { promisify } from 'node:util'
import child_process from 'node:child_process'
import { existsSync, mkdirSync } from 'node:fs'
import { writeFile } from 'node:fs/promises'
import strapiHelper from "../../utils/strapiHelper"
import { detectPdfPage, withMediaOption } from '../../utils/pdfPageMedia'

export default defineEventHandler(async (event) => {
  let data: any = { printed: [], status: 200, message: '' }
  const body = await readBody(event)
  const exec = promisify(child_process.exec)
  const config = useRuntimeConfig()
  
  const orderId = body.orderId
  const labelPrinter = body.labelPrinter || 'labelprinter-1'
  const defaultPrinter = 'default' // CUPS printer name for A4/Letter PDFs
  
  if (!orderId) {
    return { printed: [], status: 400, message: 'Order ID is required' }
  }

  console.log(`[Order Attachment Print] Starting for order ID: ${orderId}, Label printer: ${labelPrinter}`)

  try {
    // Step 1: Get the Strapi attachment record for this order (AD_Table_ID 259 = C_Order)
    const attachmentRecordResponse: any = await strapiHelper(
      event,
      `ad-attachments?filters[AD_Table_ID][$eq]=259&filters[Record_ID][$eq]=${orderId}`,
      'GET',
      null
    )

    console.log(`[Order Attachment Print] Step 1 - Attachment record response for order ${orderId}:`, JSON.stringify(attachmentRecordResponse?.data?.[0] || 'No record'))

    if (!attachmentRecordResponse?.data?.[0]?.documentId) {
      console.log(`[Order Attachment Print] No attachment record found for order ${orderId}`)
      return { printed: [], status: 200, message: 'No attachments found for this order' }
    }

    const strapiDocumentId = attachmentRecordResponse.data[0].documentId

    // Step 2: Get the actual attachment files using the documentId
    const filesResponse: any = await strapiHelper(
      event,
      `ad-attachments/${strapiDocumentId}?populate=attachment`,
      'GET',
      null
    )

    console.log(`[Order Attachment Print] Step 2 - Files response for documentId ${strapiDocumentId}:`, JSON.stringify(filesResponse?.data?.attachment?.length || 0, null, 2))

    const files = filesResponse?.data?.attachment || []
    
    // Filter only PDF files
    const pdfFiles = files.filter((file: any) => file.mime === 'application/pdf')

    console.log(`[Order Attachment Print] Found ${files.length} total files, ${pdfFiles.length} PDF files for order ${orderId}`)

    if (pdfFiles.length === 0) {
      console.log(`[Order Attachment Print] No PDF attachments found for order ${orderId}`)
      return { printed: [], status: 200, message: 'No PDF attachments found' }
    }

    const pathName = `order-attachments/${new Date().getFullYear()}`
    const filePath = `/root/storage/${pathName}`
    
    // Ensure directory exists
    if (!existsSync(filePath)) {
      mkdirSync(filePath, { recursive: true })
    }

    for (const pdfFile of pdfFiles) {
      try {
        // Download the PDF file from Strapi
        // Try multiple URL patterns: direct url, files-api with hash, or strapiupload base
        let pdfUrl = ''

        // Log available file properties for debugging
        console.log(`[Order Attachment Print] File properties:`, JSON.stringify({
          name: pdfFile.name,
          hash: pdfFile.hash,
          ext: pdfFile.ext,
          url: pdfFile.url,
          mime: pdfFile.mime
        }))

        // Use strapiupload config (direct Strapi URL) with files-api endpoint
        const strapiBase = config.api.strapiupload || 'http://127.0.0.1:1337'
        pdfUrl = `${strapiBase}/files-api/${pdfFile.hash}${pdfFile.ext}`

        console.log(`[Order Attachment Print] Downloading file from: ${pdfUrl}`)

        const pdfResponse = await $fetch(pdfUrl, {
          responseType: 'arrayBuffer'
        })
        
        const pdfBuffer = Buffer.from(pdfResponse as ArrayBuffer)
        const fileName = `${Date.now()}-${pdfFile.name}`
        const fullFilePath = `${filePath}/${fileName}`
        
        // Save the PDF temporarily
        await writeFile(fullFilePath, pdfBuffer)
        
        // Page size decides the queue: labels → label printer, A5/A4 paper → the
        // paper queue with an explicit media size (see server/utils/pdfPageMedia.ts).
        const page = await detectPdfPage(fullFilePath)
        const pageSize = { width: page.width, height: page.height, isSmall: page.kind === 'label' }

        const printerToUse = pageSize.isSmall ? labelPrinter : defaultPrinter
        const printOptions = pageSize.isSmall ? '' : withMediaOption('-o sides=one-sided', page)

        console.log(`[Order Attachment Print] File: ${pdfFile.name}, Size: ${pageSize.width}x${pageSize.height} (${page.kind}), Printer: ${printerToUse}, Options: ${printOptions}`)

        // Print the PDF
        const printCommand = `lp -d ${printerToUse} ${printOptions} "${fullFilePath}"`
        console.log(`[Order Attachment Print] Executing: ${printCommand}`)

        const { stdout, stderr } = await exec(printCommand)

        console.log(`[Order Attachment Print] Print result - stdout: ${stdout}, stderr: ${stderr}`)

        // lp command returns success if stdout contains "request id"
        const printSuccess = stdout && stdout.includes('request id')

        data.printed.push({
          fileName: pdfFile.name,
          fileId: pdfFile.id,
          printer: printerToUse,
          pageSize: {
            width: pageSize.width,
            height: pageSize.height,
            isSmall: pageSize.isSmall,
            kind: page.kind,
            media: page.mediaOption || null
          },
          success: printSuccess,
          stdout: stdout,
          stderr: stderr
        })
      } catch (fileErr: any) {
        console.error(`[Order Attachment Print] Error printing file ${pdfFile.name}:`, fileErr)
        data.printed.push({
          fileName: pdfFile.name,
          fileId: pdfFile.id,
          success: false,
          error: fileErr.message || 'Unknown error'
        })
      }
    }

    data.message = `Processed ${data.printed.length} PDF attachment(s)`
    
  } catch (err: any) {
    console.error('[Order Attachment Print] Error:', err)
    data = {
      printed: [],
      status: err.status || err.statusCode || 500,
      message: err.detail || err.message || err.statusMessage || 'Error printing attachments'
    }
  }

  return data
})
