// Purchase-order positions report (pdfmake, DIN A4 portrait).
// Prints/downloads the full order info: header fields + every position with
// product / Value / SKU / MPN / qty / blank "Geprüft" check box / description
// (no unit or price columns).
//
// Shared by the PO edit page (top action bar buttons). The order lines are
// fetched fresh on each run via `fetchPurchaseOrderReportLines()` so the report
// does not depend on the line table component being mounted / on its tab.
import { loadPdfMake } from '~/utils/loadPdfMake'

export interface PurchaseOrderReportLine {
  line: number | string
  product: string
  charge: string
  productSKU: string
  productMPN: string
  productValue: string
  description: string
  qtyEntered: number | string
}

// Maps the raw iDempiere `c_orderline` records (GET /api/orders/{id}/order-line)
// to the minimal shape the report needs. Same field resolution as the line table.
export const mapPurchaseOrderReportLines = (records: any[] = []): PurchaseOrderReportLine[] => {
  return records.map((item: any) => ({
    line: item?.Line || '',
    product: item?.M_Product_ID?.identifier || item?.M_Product_ID?.Name || '',
    charge: item?.C_Charge_ID?.identifier || '',
    productSKU: item?.M_Product_ID?.SKU || '',
    productMPN: item?.M_Product_ID?.mpn || item?.M_Product_ID?.MPN || '',
    productValue: item?.M_Product_ID?.Value || '',
    description: item?.Description || '',
    qtyEntered: item?.QtyEntered || 1
  })).sort((a, b) => Number(a.line) - Number(b.line))
}

export const fetchPurchaseOrderReportLines = async (orderId: string | number): Promise<PurchaseOrderReportLine[]> => {
  const res: any = await $fetch('/api/orders/' + orderId + '/order-line', {
    headers: useRequestHeaders(['cookie'])
  })
  return mapPurchaseOrderReportLines(res?.records || [])
}

export const buildPurchaseOrderReportDoc = (info: any, entries: PurchaseOrderReportLine[]) => {
  info = info || {}
  const headerPairs = [
    ['Belegnr.', info.documentNo],
    ['Status', info.docStatus],
    ['Lieferant', info.partner],
    ['Anschrift', info.partnerLocation],
    ['Organisation', info.organization],
    ['Lager', info.warehouse],
    ['Bestelldatum', info.dateOrdered],
    ['Zugesagt am', info.datePromised],
    ['Buchungsdatum', info.dateAcct],
    ['Währung', info.currency],
    ['Zahlungsbedingung', info.paymentTerm],
    ['Preisliste', info.priceList],
    ['Referenz', info.poReference],
    ['Einkäufer', info.salesRep],
    ['Beschreibung', info.description]
  ].filter(p => p[1] !== undefined && p[1] !== null && String(p[1]).trim() !== '')

  const perCol = Math.ceil(headerPairs.length / 3) || 1
  const headerColumns: any[] = []
  for (let c = 0; c < 3; c++) {
    const slice = headerPairs.slice(c * perCol, (c + 1) * perCol)
    if (!slice.length) continue
    headerColumns.push({
      width: '*',
      table: { widths: [92, '*'], body: slice.map(([k, v]) => [{ text: k, bold: true }, { text: String(v) }]) },
      layout: 'noBorders'
    })
  }

  const tableBody: any[] = [[
    { text: 'Pos.', style: 'th', alignment: 'right' },
    { text: 'Produkt', style: 'th' },
    { text: 'Value', style: 'th' },
    { text: 'SKU', style: 'th' },
    { text: 'MPN', style: 'th' },
    { text: 'Menge', style: 'th', alignment: 'right' },
    // Virtual column — intentionally empty so the printed sheet can be ticked off
    // by hand when the received quantity is checked.
    { text: 'Geprüft', style: 'th', alignment: 'center' },
    { text: 'Beschreibung', style: 'th' }
  ]]
  for (const e of entries) {
    tableBody.push([
      { text: String(e.line ?? ''), alignment: 'right' },
      { text: e.product || e.charge || '' },
      { text: e.productValue || '' },
      { text: e.productSKU || '' },
      { text: e.productMPN || '' },
      { text: String(e.qtyEntered ?? ''), alignment: 'right' },
      { text: '' },
      { text: e.description || '' }
    ])
  }
  tableBody.push([
    { text: `${entries.length} Positionen`, colSpan: 8, bold: true }, {}, {}, {}, {}, {}, {}, {}
  ])

  return {
    pageSize: 'A4',
    pageOrientation: 'portrait',
    pageMargins: [28, 30, 28, 34],
    content: [
      { text: `Bestellung ${info.documentNo || ''} — Report`, fontSize: 14, bold: true, margin: [0, 0, 0, 8] },
      { columns: headerColumns, columnGap: 14, fontSize: 8, margin: [0, 0, 0, 10] },
      {
        table: {
          headerRows: 1,
          dontBreakRows: true,
          widths: [22, '*', 54, 54, 54, 30, 36, 110],
          body: tableBody
        },
        layout: {
          hLineColor: () => '#cccccc',
          vLineColor: () => '#cccccc',
          hLineWidth: () => 0.5,
          vLineWidth: () => 0.5
        }
      },
      { text: `Erstellt: ${new Date().toLocaleString('de-DE', { timeZone: 'Europe/Berlin' })}`, fontSize: 8, color: '#777777', margin: [0, 10, 0, 0] }
    ],
    styles: {
      th: { bold: true, fontSize: 8, fillColor: '#f0f0f0', margin: [0, 2, 0, 2] }
    },
    defaultStyle: { fontSize: 8 }
  }
}

// Fetches the lines, builds the PDF and either opens the print dialog or downloads it.
export const runPurchaseOrderReport = async (info: any, mode: 'print' | 'download' = 'download') => {
  const orderId = info?.id
  if (!orderId) throw new Error('Order not loaded')
  const [entries, pdfMake] = await Promise.all([
    fetchPurchaseOrderReportLines(orderId),
    loadPdfMake()
  ])
  const pdf = pdfMake.createPdf(buildPurchaseOrderReportDoc(info, entries))
  if (mode === 'print') {
    pdf.print()
  } else {
    pdf.download(`Bestellung-${info?.documentNo || orderId}-Report.pdf`)
  }
}
