/**
 * Parcel-contents report (multi-parcel commission) — shared logic for the
 * modal on the sales-order edit page and its A4 PDF download.
 *
 * Source is the M_InOut.commission_parcels_json snapshot written by the
 * commission page (see server/api/commission/parcels/contents.post.ts for the
 * shape). The report shows, per parcel, which article was scanned into it —
 * grouped by the code the operator scanned: the FBA relabel code
 * (C_OrderLine.printLabelCode) when one was used, otherwise the product SKU.
 */

import { loadPdfMake } from '~/utils/loadPdfMake'

export interface ParcelContentsItem {
  inoutLineId?: number | null
  orderLineId?: number | null
  productId?: number | null
  sku?: string
  name?: string
  qty?: number
  weight?: number
  scannedCodes?: Array<string | null>
  printLabelCode?: string | null
}

export interface ParcelContentsParcel {
  no?: number
  weight?: number
  trackingNo?: string | null
  items?: ParcelContentsItem[]
}

export interface ParcelContents {
  v?: number
  createdAt?: string
  totalWeight?: number
  parcels: ParcelContentsParcel[]
}

export interface ParcelContentsRow {
  code: string        // grouping code: printLabelCode > SKU > name
  isLabelCode: boolean // true when the code is a relabel/printLabelCode
  name: string
  sku: string
  qty: number
  weight: number
}

export const useParcelContentsDoc = () => {
  // Tolerant parse of the raw column value (string or already-parsed object).
  const parseParcelContents = (raw: any): ParcelContents | null => {
    try {
      const data = typeof raw === 'string' ? JSON.parse(raw) : raw
      if (!data || !Array.isArray(data.parcels) || data.parcels.length === 0) return null
      return data
    } catch {
      return null
    }
  }

  // Group a parcel's items by the scanned/label code so e.g. two order lines
  // relabeled with the same number collapse into one row with the summed qty.
  const groupParcelItems = (parcel: ParcelContentsParcel): ParcelContentsRow[] => {
    const groups: Record<string, ParcelContentsRow> = {}
    for (const item of (parcel?.items || [])) {
      const labelCode = String(item?.printLabelCode ?? '').trim()
      const sku = String(item?.sku ?? '').trim()
      const name = String(item?.name ?? '').trim()
      const code = labelCode || sku || name || '-'
      const key = (labelCode ? 'L:' : 'S:') + code
      if (!groups[key]) {
        groups[key] = { code, isLabelCode: !!labelCode, name, sku, qty: 0, weight: 0 }
      }
      groups[key].qty += Number(item?.qty || 0)
      groups[key].weight = Number((groups[key].weight + Number(item?.weight || 0)).toFixed(2))
      // Keep the first non-empty name/sku (grouped lines share the product anyway)
      if (!groups[key].name && name) groups[key].name = name
      if (!groups[key].sku && sku) groups[key].sku = sku
    }
    return Object.values(groups)
  }

  const parcelTotals = (data: ParcelContents) => {
    const parcels = data?.parcels || []
    const pieces = parcels.reduce((sum, p) => sum + (p.items || []).reduce((s, i) => s + Number(i?.qty || 0), 0), 0)
    const weight = Number(data?.totalWeight ?? parcels.reduce((sum, p) => sum + Number(p?.weight || 0), 0)) || 0
    return { parcels: parcels.length, pieces, weight: Number(weight.toFixed(2)) }
  }

  const formatCreatedAt = (createdAt?: string) => {
    if (!createdAt) return ''
    const d = new Date(createdAt)
    return isNaN(d.getTime()) ? '' : d.toLocaleString('de-DE', { timeZone: 'Europe/Berlin' })
  }

  /**
   * DIN-A4 report: one section per parcel (tracking + weight in the heading),
   * grouped item rows, grand-total footer. German labels — same convention as
   * buildRelabelReportDoc.
   */
  const buildParcelContentsDoc = async (data: ParcelContents, shipmentDocNo: string, orderDocNo: string = '') => {
    const pdfMake = await loadPdfMake()
    const totals = parcelTotals(data)

    const content: any[] = [
      { text: `Paketinhalt – Sendung ${shipmentDocNo || ''}`, fontSize: 15, bold: true },
      {
        text: [
          orderDocNo ? `Auftrag ${orderDocNo} · ` : '',
          `Kommissioniert: ${formatCreatedAt(data?.createdAt) || '-'}`
        ].join(''),
        fontSize: 9, color: '#555555', margin: [0, 3, 0, 2]
      },
      { text: 'Übersicht: welcher Artikel wurde in welches Paket gescannt (gruppiert nach gescanntem Code / Etiketten-Code).', fontSize: 9, color: '#555555', margin: [0, 0, 0, 12] }
    ]

    for (const parcel of (data?.parcels || [])) {
      const headParts = [`Paket ${parcel?.no ?? '?'}`]
      if (parcel?.trackingNo) headParts.push(`Tracking: ${parcel.trackingNo}`)
      headParts.push(`${Number(parcel?.weight || 0).toFixed(2)} kg`)
      content.push({ text: headParts.join('  ·  '), fontSize: 11, bold: true, margin: [0, 10, 0, 4] })

      const tableBody: any[] = [[
        { text: 'Code', style: 'th' },
        { text: 'Artikel', style: 'th' },
        { text: 'SKU', style: 'th' },
        { text: 'Menge', style: 'th', alignment: 'right' },
        { text: 'Gewicht (kg)', style: 'th', alignment: 'right' }
      ]]
      const rows = groupParcelItems(parcel)
      for (const r of rows) {
        tableBody.push([
          { text: r.code, bold: r.isLabelCode },
          { text: r.name },
          { text: r.sku },
          { text: String(r.qty), alignment: 'right', bold: true },
          { text: Number(r.weight || 0).toFixed(2), alignment: 'right' }
        ])
      }
      const parcelQty = rows.reduce((s, r) => s + r.qty, 0)
      tableBody.push([
        { text: '', colSpan: 2 }, {},
        { text: 'Summe', bold: true, alignment: 'right' },
        { text: String(parcelQty), bold: true, alignment: 'right' },
        { text: Number(parcel?.weight || 0).toFixed(2), bold: true, alignment: 'right' }
      ])

      content.push({
        table: {
          headerRows: 1,
          widths: [120, '*', 90, 40, 60],
          body: tableBody
        },
        layout: {
          hLineColor: () => '#cccccc',
          vLineColor: () => '#cccccc',
          hLineWidth: () => 0.5,
          vLineWidth: () => 0.5
        }
      })
    }

    content.push({
      text: `Gesamt: ${totals.parcels} Pakete · ${totals.pieces} Artikel · ${totals.weight.toFixed(2)} kg`,
      fontSize: 11, bold: true, margin: [0, 14, 0, 0]
    })
    content.push({
      text: `Erstellt: ${new Date().toLocaleString('de-DE', { timeZone: 'Europe/Berlin' })}`,
      fontSize: 8, color: '#777777', margin: [0, 8, 0, 0]
    })

    const docDefinition: any = {
      pageSize: 'A4',
      pageMargins: [40, 50, 40, 50],
      content,
      styles: {
        th: { bold: true, fontSize: 9, fillColor: '#f0f0f0', margin: [0, 2, 0, 2] }
      },
      defaultStyle: { fontSize: 9 }
    }

    return pdfMake.createPdf(docDefinition)
  }

  return { parseParcelContents, groupParcelItems, parcelTotals, formatCreatedAt, buildParcelContentsDoc }
}
