import nodemailer from 'nodemailer'
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib'
import refreshTokenHelper from "../../utils/refreshTokenHelper"
import forceLogoutHelper from "../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../utils/errorHandlingHelper"

interface TransactionRecord {
  id: string | number
  movementDate: string
  movementQty: number
  movementType: string
  movementTypeId: string
  locator: string
  bpartnerName: string
  externalOrderId: string
}

const formatDate = (date: Date, lang: string) => {
  const isGerman = lang.startsWith('de')
  return date.toLocaleDateString(isGerman ? 'de-DE' : 'en-US', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  })
}

const formatMovementDate = (dateStr: string, lang: string) => {
  if (!dateStr) return ''
  const isGerman = lang.startsWith('de')
  const date = new Date(dateStr)
  return date.toLocaleDateString(isGerman ? 'de-DE' : 'en-US')
}

const getMovementTypeInfo = (qty: number) => {
  const isPositive = (qty || 0) > 0
  return {
    label: isPositive ? 'IN' : 'OUT',
    color: isPositive ? rgb(0.15, 0.68, 0.38) : rgb(0.91, 0.30, 0.24)
  }
}

const generateCsvReport = (records: TransactionRecord[], productName: string, lang: string) => {
  const isGerman = lang.startsWith('de')

  const headers = isGerman
    ? ['Nr.', 'Typ', 'Datum', 'Menge', 'Externe Bestellnummer', 'Geschaeftspartner', 'Lagerort', 'Bewegungsart']
    : ['No.', 'Type', 'Date', 'Quantity', 'External Order ID', 'Business Partner', 'Locator', 'Movement Type']

  const totalRows = records.length
  const rows = records.map((r, index) => {
    const typeInfo = getMovementTypeInfo(r.movementQty)
    const qty = r.movementQty || 0
    const qtyStr = qty > 0 ? `+${qty}` : `${qty}`
    return [
      totalRows - index,
      typeInfo.label,
      formatMovementDate(r.movementDate, lang),
      qtyStr,
      r.externalOrderId || '',
      r.bpartnerName || '',
      r.locator || '',
      r.movementType || ''
    ]
  })

  const csvContent = [
    headers.join(';'),
    ...rows.map(row => row.map(cell => `"${String(cell).replace(/"/g, '""')}"`).join(';'))
  ].join('\n')

  return Buffer.from('\uFEFF' + csvContent, 'utf-8')
}

const generatePdfReport = async (records: TransactionRecord[], productName: string, productSku: string, productValue: string, productMpn: string, lang: string) => {
  const isGerman = lang.startsWith('de')
  const pdfDoc = await PDFDocument.create()
  const font = await pdfDoc.embedFont(StandardFonts.Helvetica)
  const fontBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold)

  // Use landscape for better fit (matching jsPDF dimensions)
  const pageWidth = 841.89 // A4 landscape
  const pageHeight = 595.28
  const margin = 14 // Match client-side margin
  const lineHeight = 6
  const headerHeight = 8

  // Column positions matching client-side (x positions)
  const colX = {
    no: 14,
    type: 28,
    date: 50,
    qty: 85,
    extOrder: 115,
    bpartner: 165,
    locator: 235,
    movType: 265
  }

  const addNewPage = () => {
    return pdfDoc.addPage([pageWidth, pageHeight])
  }

  const drawTableHeader = (page: any, yPos: number) => {
    const fontSize = 8
    page.drawText('#', { x: colX.no, y: yPos, size: fontSize, font: fontBold })
    page.drawText('Type', { x: colX.type, y: yPos, size: fontSize, font: fontBold })
    page.drawText('Date', { x: colX.date, y: yPos, size: fontSize, font: fontBold })
    page.drawText(isGerman ? 'Menge' : 'Quantity', { x: colX.qty, y: yPos, size: fontSize, font: fontBold })
    page.drawText(isGerman ? 'Ext. Bestellnr.' : 'External Order ID', { x: colX.extOrder, y: yPos, size: fontSize, font: fontBold })
    page.drawText(isGerman ? 'Geschaeftspartner' : 'Business Partner', { x: colX.bpartner, y: yPos, size: fontSize, font: fontBold })
    page.drawText(isGerman ? 'Lagerort' : 'Locator', { x: colX.locator, y: yPos, size: fontSize, font: fontBold })
    page.drawText(isGerman ? 'Bewegungsart' : 'Movement Type', { x: colX.movType, y: yPos, size: fontSize, font: fontBold })
    return yPos - headerHeight - 5
  }

  const drawRow = (page: any, record: TransactionRecord, yPos: number, rowNumber: number) => {
    const fontSize = 8

    const qty = record.movementQty || 0
    const typeInfo = getMovementTypeInfo(qty)
    const qtyStr = qty > 0 ? `+${qty}` : `${qty}`

    // Row number (grey)
    page.drawText(String(rowNumber), { x: colX.no, y: yPos, size: fontSize, font, color: rgb(0.4, 0.4, 0.4) })

    // Type with color (green for IN, red for OUT)
    page.drawText(typeInfo.label, { x: colX.type, y: yPos, size: fontSize, font: fontBold, color: typeInfo.color })

    // Date
    page.drawText(formatMovementDate(record.movementDate, lang), { x: colX.date, y: yPos, size: fontSize, font })

    // Quantity with color
    page.drawText(qtyStr, { x: colX.qty, y: yPos, size: fontSize, font: fontBold, color: typeInfo.color })

    // External Order ID
    page.drawText(record.externalOrderId || '', { x: colX.extOrder, y: yPos, size: fontSize, font })

    // Business Partner (truncate if needed)
    let bpartner = record.bpartnerName || ''
    if (bpartner.length > 35) bpartner = bpartner.substring(0, 32) + '...'
    page.drawText(bpartner, { x: colX.bpartner, y: yPos, size: fontSize, font })

    // Locator
    page.drawText(record.locator || '', { x: colX.locator, y: yPos, size: fontSize, font })

    // Movement Type
    page.drawText(record.movementType || '', { x: colX.movType, y: yPos, size: fontSize, font })

    return yPos - lineHeight
  }

  let page = addNewPage()
  let yPos = pageHeight - 20 // Start from top with small margin

  // Calculate summary stats
  const totalIn = records.filter(r => (r.movementQty || 0) > 0).reduce((sum, r) => sum + (r.movementQty || 0), 0)
  const totalOut = records.filter(r => (r.movementQty || 0) < 0).reduce((sum, r) => sum + Math.abs(r.movementQty || 0), 0)
  const netChange = totalIn - totalOut

  // Title
  const titleLabel = isGerman ? 'Produkthistorie: ' : 'Product History: '
  page.drawText(titleLabel + productName, { x: margin, y: yPos, size: 16, font: fontBold })
  yPos -= 16

  // Product details (Value, SKU, MPN)
  if (productValue) {
    page.drawText(`${isGerman ? 'Artikelnr.' : 'Article No.'}: ${productValue}`, { x: margin, y: yPos, size: 10, font })
    yPos -= 12
  }
  if (productSku) {
    page.drawText(`SKU: ${productSku}`, { x: margin, y: yPos, size: 10, font })
    yPos -= 12
  }
  if (productMpn) {
    page.drawText(`MPN: ${productMpn}`, { x: margin, y: yPos, size: 10, font })
    yPos -= 12
  }

  // Generated date/time
  const dateLabel = isGerman ? 'Erstellt: ' : 'Generated: '
  page.drawText(dateLabel + formatDate(new Date(), lang), { x: margin, y: yPos, size: 10, font })
  yPos -= 14

  // Summary cards (matching client-side dimensions: 60x18 with gap 8)
  const cardWidth = 60
  const cardHeight = 18
  const cardGap = 8
  const cardStartX = margin
  const cardY = yPos - cardHeight

  // Helper to draw a card (matching client-side style)
  const drawCard = (x: number, value: string, label: string, bgColor: { r: number, g: number, b: number }) => {
    // Draw filled rectangle
    page.drawRectangle({
      x: x,
      y: cardY,
      width: cardWidth,
      height: cardHeight,
      color: rgb(bgColor.r, bgColor.g, bgColor.b)
    })
    // Value text (top portion of card) - positioned like jsPDF: cardY + 8 from top
    page.drawText(value, { x: x + 5, y: cardY + cardHeight - 8, size: 12, font: fontBold, color: rgb(1, 1, 1) })
    // Label text (bottom portion of card) - positioned like jsPDF: cardY + 14 from top
    page.drawText(label, { x: x + 5, y: cardY + 3, size: 7, font, color: rgb(1, 1, 1) })
  }

  // Card 1: Total Transactions (blue/primary - rgb(50, 115, 220) = 0.196, 0.451, 0.863)
  drawCard(cardStartX, String(records.length), isGerman ? 'Transaktionen' : 'Total Transactions', { r: 0.196, g: 0.451, b: 0.863 })

  // Card 2: Total IN (green - rgb(39, 174, 96) = 0.153, 0.682, 0.376)
  drawCard(cardStartX + cardWidth + cardGap, `+${totalIn}`, isGerman ? 'Eingang' : 'Total IN', { r: 0.153, g: 0.682, b: 0.376 })

  // Card 3: Total OUT (red - rgb(231, 76, 60) = 0.906, 0.298, 0.235)
  drawCard(cardStartX + 2 * (cardWidth + cardGap), `-${totalOut}`, isGerman ? 'Ausgang' : 'Total OUT', { r: 0.906, g: 0.298, b: 0.235 })

  // Card 4: Net Change (info blue for positive rgb(32, 156, 238) = 0.125, 0.612, 0.933, warning orange for negative rgb(255, 166, 0) = 1, 0.651, 0)
  const netColor = netChange >= 0 ? { r: 0.125, g: 0.612, b: 0.933 } : { r: 1, g: 0.651, b: 0 }
  drawCard(cardStartX + 3 * (cardWidth + cardGap), `${netChange >= 0 ? '+' : ''}${netChange}`, isGerman ? 'Nettoveraend.' : 'Net Change', netColor)

  yPos = cardY - 12

  // Draw table header
  yPos = drawTableHeader(page, yPos)

  // Draw rows with reversed numbering (1 for oldest)
  const totalRows = records.length
  const bottomMargin = 30
  records.forEach((record, index) => {
    if (yPos < bottomMargin) {
      page = addNewPage()
      yPos = pageHeight - 20
      yPos = drawTableHeader(page, yPos)
    }
    const rowNumber = totalRows - index
    yPos = drawRow(page, record, yPos, rowNumber)
  })

  const pdfBytes = await pdfDoc.save()
  return Buffer.from(pdfBytes)
}

const generateHtmlEmailDE = (productName: string, productSku: string, recordCount: number, totalIn: number, totalOut: number) => {
  return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Produkthistorie - ${productName}</title>
</head>
<body style="margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.6; color: #333333; background-color: #f4f4f4;">
  <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color: #f4f4f4;">
    <tr>
      <td style="padding: 20px 0;">
        <table role="presentation" width="600" cellspacing="0" cellpadding="0" style="margin: 0 auto; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
          <tr>
            <td style="background-color: #2c3e50; padding: 30px 40px; text-align: center;">
              <h1 style="margin: 0; color: #ffffff; font-size: 24px; font-weight: 600;">Produkthistorie</h1>
              <p style="margin: 10px 0 0 0; color: #ffffff; font-size: 16px;">${productName}${productSku ? ` (SKU: ${productSku})` : ''}</p>
            </td>
          </tr>
          <tr>
            <td style="padding: 40px;">
              <p style="margin: 0 0 20px 0;">Sehr geehrte Damen und Herren,</p>
              <p style="margin: 0 0 20px 0;">anbei finden Sie die Transaktionshistorie als Anhang.</p>
              <table role="presentation" cellspacing="0" cellpadding="0" style="width: 100%; border-collapse: collapse; margin: 20px 0; border: 1px solid #e0e0e0; border-radius: 6px;">
                <tr style="background-color: #f8f9fa;">
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0; font-weight: 600;">Anzahl Transaktionen</td>
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0;">${recordCount}</td>
                </tr>
                <tr>
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0; font-weight: 600;">Gesamt Eingang</td>
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0; color: #27ae60; font-weight: 600;">+${totalIn}</td>
                </tr>
                <tr>
                  <td style="padding: 12px 16px; font-weight: 600;">Gesamt Ausgang</td>
                  <td style="padding: 12px 16px; color: #e74c3c; font-weight: 600;">-${totalOut}</td>
                </tr>
              </table>
              <p style="margin: 20px 0 0 0;">Mit freundlichen Gruessen</p>
            </td>
          </tr>
          <tr>
            <td style="background-color: #f8f9fa; padding: 20px 40px; text-align: center; border-top: 1px solid #eeeeee;">
              <p style="margin: 0; font-size: 12px; color: #888888;">
                Diese E-Mail wurde automatisch versendet.
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>
`
}

const generateHtmlEmailEN = (productName: string, productSku: string, recordCount: number, totalIn: number, totalOut: number) => {
  return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Product History - ${productName}</title>
</head>
<body style="margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 1.6; color: #333333; background-color: #f4f4f4;">
  <table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color: #f4f4f4;">
    <tr>
      <td style="padding: 20px 0;">
        <table role="presentation" width="600" cellspacing="0" cellpadding="0" style="margin: 0 auto; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
          <tr>
            <td style="background-color: #2c3e50; padding: 30px 40px; text-align: center;">
              <h1 style="margin: 0; color: #ffffff; font-size: 24px; font-weight: 600;">Product History</h1>
              <p style="margin: 10px 0 0 0; color: #ffffff; font-size: 16px;">${productName}${productSku ? ` (SKU: ${productSku})` : ''}</p>
            </td>
          </tr>
          <tr>
            <td style="padding: 40px;">
              <p style="margin: 0 0 20px 0;">Dear Sir or Madam,</p>
              <p style="margin: 0 0 20px 0;">Please find attached the transaction history.</p>
              <table role="presentation" cellspacing="0" cellpadding="0" style="width: 100%; border-collapse: collapse; margin: 20px 0; border: 1px solid #e0e0e0; border-radius: 6px;">
                <tr style="background-color: #f8f9fa;">
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0; font-weight: 600;">Total Transactions</td>
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0;">${recordCount}</td>
                </tr>
                <tr>
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0; font-weight: 600;">Total IN</td>
                  <td style="padding: 12px 16px; border-bottom: 1px solid #e0e0e0; color: #27ae60; font-weight: 600;">+${totalIn}</td>
                </tr>
                <tr>
                  <td style="padding: 12px 16px; font-weight: 600;">Total OUT</td>
                  <td style="padding: 12px 16px; color: #e74c3c; font-weight: 600;">-${totalOut}</td>
                </tr>
              </table>
              <p style="margin: 20px 0 0 0;">Best regards</p>
            </td>
          </tr>
          <tr>
            <td style="background-color: #f8f9fa; padding: 20px 40px; text-align: center; border-top: 1px solid #eeeeee;">
              <p style="margin: 0; font-size: 12px; color: #888888;">
                This email was sent automatically.
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>
`
}

const handleFunc = async (event: any, authToken: any = null) => {
  let data: any = { status: 200, message: 'Transaction report sent successfully' }
  const token = authToken ?? await getTokenHelper(event)
  const body = await readBody(event)

  const {
    toEmail,
    ccEmail,
    subject,
    records,
    productName,
    productSku = '',
    productValue = '',
    productMpn = '',
    language = 'de_DE',
    format = 'pdf'
  } = body

  if (!toEmail) {
    return { status: 400, message: 'Recipient email is required' }
  }

  if (!records || !Array.isArray(records) || records.length === 0) {
    return { status: 400, message: 'No records to send' }
  }

  if (!productName) {
    return { status: 400, message: 'Product name is required' }
  }

  const isGerman = language.startsWith('de')
  const totalIn = records.filter((r: TransactionRecord) => (r.movementQty || 0) > 0).reduce((sum: number, r: TransactionRecord) => sum + (r.movementQty || 0), 0)
  const totalOut = records.filter((r: TransactionRecord) => (r.movementQty || 0) < 0).reduce((sum: number, r: TransactionRecord) => sum + Math.abs(r.movementQty || 0), 0)

  // Generate attachment based on format
  let attachmentBuffer: Buffer
  let attachmentFilename: string
  let attachmentContentType: string

  if (format === 'csv') {
    attachmentBuffer = generateCsvReport(records, productName, language)
    attachmentFilename = isGerman
      ? `Produkthistorie_${productName.replace(/[^a-zA-Z0-9]/g, '_')}_${new Date().toISOString().split('T')[0]}.csv`
      : `Product_History_${productName.replace(/[^a-zA-Z0-9]/g, '_')}_${new Date().toISOString().split('T')[0]}.csv`
    attachmentContentType = 'text/csv; charset=utf-8'
  } else {
    attachmentBuffer = await generatePdfReport(records, productName, productSku, productValue, productMpn, language)
    attachmentFilename = isGerman
      ? `Produkthistorie_${productName.replace(/[^a-zA-Z0-9]/g, '_')}_${new Date().toISOString().split('T')[0]}.pdf`
      : `Product_History_${productName.replace(/[^a-zA-Z0-9]/g, '_')}_${new Date().toISOString().split('T')[0]}.pdf`
    attachmentContentType = 'application/pdf'
  }

  // Generate HTML email
  const htmlContent = isGerman
    ? generateHtmlEmailDE(productName, productSku, records.length, totalIn, totalOut)
    : generateHtmlEmailEN(productName, productSku, records.length, totalIn, totalOut)

  // Create transporter
  const transporter = nodemailer.createTransport({
    host: 'localhost',
    port: 25,
    secure: false,
    tls: {
      rejectUnauthorized: false
    }
  })

  // Build email options
  const emailOptions: any = {
    from: 'no-reply@logyou.de',
    to: toEmail,
    subject: subject || (isGerman ? `Produkthistorie - ${productName}` : `Product History - ${productName}`),
    html: htmlContent,
    attachments: [
      {
        filename: attachmentFilename,
        content: attachmentBuffer,
        contentType: attachmentContentType
      }
    ]
  }

  if (ccEmail) {
    emailOptions.cc = ccEmail
  }

  // Send email
  try {
    await transporter.sendMail(emailOptions)
  } catch (err: any) {
    console.error('Email send error:', err)
    return { status: 500, message: `Failed to send transaction report: ${err.message}` }
  }

  return data
}

export default defineEventHandler(async (event) => {
  let data: any = {}

  try {
    data = await handleFunc(event)
  } catch (err: any) {
    try {
      let authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error: any) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
    }
  }

  return data
})
