import dhlHelper from "../../../../utils/dhlHelper"
import dhlCustomHelper from "../../../../utils/dhlCustomHelper"
import getTokenHelper from "../../../../utils/getTokenHelper"
import fetchHelper from "../../../../utils/fetchHelper"
import errorHandlingHelper from "../../../../utils/errorHandlingHelper"

/**
 * Re-fetch DHL label(s) for a shipment (reprint).
 *
 * Query:
 *  - `inout_id` (preferred): the shipment numbers are read FRESH from
 *    M_InOut.DHL_Shipment_Code (fallback TrackingNo). The order edit page is
 *    keep-alive'd, so a reprint opened after a reset + re-commissioning elsewhere
 *    would otherwise ask DHL for the OLD number still held in page state — DHL
 *    happily returns cancelled labels, so the old label got printed. Also resolves
 *    the order source's custom DHL account (same rule as label creation / cancel).
 *  - `shipment_code`: used when no inout_id is given (or the record has none).
 *
 * Multi-parcel shipments store ALL numbers comma-joined (dhl/multi.post.ts).
 * DHL's GET /orders takes one `shipment` query param per number (max 30) — a
 * comma-joined value only resolved the first label, so the reprint silently lost
 * every additional parcel. Split → one param each → `items[]` = one label per parcel.
 */
const splitCodes = (v: any): string[] =>
  String(v ?? '')
    .split(',')
    .map(s => s.trim())
    .filter(Boolean)
    .slice(0, 30)

const loadShipmentContext = async (event: any, inoutId: any) => {
  const ctx: { codes: string[]; custom: any } = { codes: [], custom: null }
  if (!inoutId || isNaN(Number(inoutId))) return ctx
  try {
    const token = await getTokenHelper(event)
    const inout: any = await fetchHelper(event, `models/m_inout/${inoutId}?$expand=c_order_id`, 'GET', token, null)
    ctx.codes = splitCodes(inout?.DHL_Shipment_Code ?? inout?.dhl_shipment_code)
    if (ctx.codes.length === 0) ctx.codes = splitCodes(inout?.TrackingNo)

    const orderSourceId = inout?.C_Order_ID?.C_OrderSource_ID?.id
    if (orderSourceId) {
      const os: any = await fetchHelper(event, `models/c_ordersource/${orderSourceId}`, 'GET', token, null)
      if ((os?.DHL_USE_CUSTOM ?? os?.dhl_use_custom) == true && (os?.DHLURL ?? os?.dhlurl)) {
        ctx.custom = {
          dhlurl: os.DHLURL ?? os.dhlurl,
          dhlkey: os.DHLKEY ?? os.dhlkey,
          dhlsecret: os.DHLSECRET ?? os.dhlsecret,
          dhluser: os.DHLUSER ?? os.dhluser,
          dhlpass: os.DHLPASS ?? os.dhlpass,
          iscustom: true
        }
      }
    }
  } catch (err: any) {
    // Fail-soft: fall back to the caller's shipment_code + main account.
    console.warn('[DHL label GET] shipment lookup failed, using query codes / main account:', err?.message || err)
  }
  return ctx
}

export default defineEventHandler(async (event) => {
  let data: any = null
  const query = getQuery(event)

  const ctx = await loadShipmentContext(event, query?.inout_id)
  const codes = ctx.codes.length > 0 ? ctx.codes : splitCodes(query?.shipment_code)

  if (codes.length === 0) {
    return { items: [], status: 400, message: 'shipment_code or inout_id is required' }
  }

  const url = 'shipping/v2/orders?' +
    codes.map(c => 'shipment=' + encodeURIComponent(c)).join('&') +
    '&printFormat=910-300-400'

  try {
    const res: any = ctx.custom
      ? await dhlCustomHelper(event, ctx.custom, url, 'GET', null)
      : await dhlHelper(event, url, 'GET', null)
    if (res) {
      data = { ...res, shipmentCodes: codes }
    }
  } catch (err: any) {
    data = errorHandlingHelper(err?.data ?? err, err?.data ?? err)
  }

  return data
})
