import { string } from 'alga-js'
import fetchHelper from './fetchHelper'

/**
 * Productions (m_production) linked to the lines of a sales order via
 * M_Production.C_OrderLine_ID, plus a per-line aggregation (produced vs.
 * planned qty). Shared by `orders/[id]/productions.get.ts` (position chips)
 * and `orders/[id]/roadmap.get.ts` (order roadmap).
 *
 * iDempiere REST has no join filter (C_OrderLine_ID.C_Order_ID), so the line
 * ids are resolved first and the productions are queried with an OR chain
 * (the `in` operator is not reliable on this backend). Pass `lineIds` when the
 * caller already has the order lines to save the extra round trip.
 */
export interface OrderProductionRecord {
  id: number
  documentNo: string
  name: string
  description: string
  movementDate: string
  datePromised: string
  productionQty: number
  docStatusId: string
  docStatus: string
  processed: boolean
  isCreated: boolean
  orderLineId: number | null
  productId: number | null
  product: string
  bomId: number | null
  locator: string
  organizationId: number | null
}

export const mapProductionRecord = (p: any): OrderProductionRecord => {
  const docStatusId = p.DocStatus?.id || p.DocStatus || ''
  return {
    id: p.id,
    documentNo: p.DocumentNo || '',
    name: p.Name || '',
    description: p.Description || '',
    movementDate: p.MovementDate || '',
    datePromised: p.DatePromised || '',
    // Planned/produced quantity of the finished product. For a completed
    // production this IS the produced qty (the finished-good line is booked
    // with +ProductionQty); for drafts it's the planned qty.
    productionQty: Number(p.ProductionQty) || 0,
    docStatusId,
    docStatus: p.DocStatus?.identifier || docStatusId,
    processed: p.Processed === true,
    isCreated: (p.IsCreated?.id ?? p.IsCreated) === 'Y' || p.IsCreated === true,
    orderLineId: p.C_OrderLine_ID?.id || null,
    productId: p.M_Product_ID?.id || null,
    product: p.M_Product_ID?.identifier || '',
    bomId: p.PP_Product_BOM_ID?.id || null,
    locator: p.M_Locator_ID?.identifier || '',
    organizationId: p.AD_Org_ID?.id || null
  }
}

export const fetchOrderLineIds = async (event: any, token: any, orderId: number | string): Promise<number[]> => {
  const id = Number(orderId)
  if (!Number.isFinite(id) || id <= 0) return []
  const linesRes: any = await fetchHelper(event, `models/c_orderline?$filter=${string.urlEncode('C_Order_ID eq ' + id)}&$select=Line,QtyOrdered,M_Product_ID&$top=500`, 'GET', token, null)
  return (linesRes?.records || []).map((l: any) => Number(l.id)).filter((n: number) => Number.isFinite(n) && n > 0)
}

export const fetchOrderProductions = async (event: any, token: any, orderId: number | string, lineIds?: number[]) => {
  const ids = Array.isArray(lineIds) ? lineIds.filter((n) => Number.isFinite(n) && n > 0) : await fetchOrderLineIds(event, token, orderId)
  if (ids.length === 0) {
    return { records: [] as OrderProductionRecord[], byOrderLine: {} as Record<string, any> }
  }

  const filter = ids.map((lid) => 'C_OrderLine_ID eq ' + lid).join(' OR ')
  const res: any = await fetchHelper(event, `models/m_production?$filter=${string.urlEncode(filter)}&$orderby=${string.urlEncode('MovementDate desc, Created desc')}&$top=200`, 'GET', token, null)
  const records: OrderProductionRecord[] = (res?.records || []).map(mapProductionRecord)

  // Per-line aggregation: total produced (completed/closed only) vs. planned.
  const byOrderLine: Record<string, any> = {}
  for (const r of records) {
    if (!r.orderLineId) continue
    const key = String(r.orderLineId)
    if (!byOrderLine[key]) byOrderLine[key] = { productions: [], producedQty: 0, plannedQty: 0 }
    byOrderLine[key].productions.push(r)
    if (['CO', 'CL'].includes(r.docStatusId)) byOrderLine[key].producedQty += r.productionQty
    else if (!['VO', 'RE'].includes(r.docStatusId)) byOrderLine[key].plannedQty += r.productionQty
  }

  return { records, byOrderLine }
}
