import { string } from 'alga-js'

export const useOpenShipments = () => {
  const openShipments = ref<any[]>([])
  const isLoading = ref(false)
  const error = ref<string | null>(null)
  const lastFetched = ref<Date | null>(null)

  // Shipment list — direct-Postgres endpoint (server/api/inouts/open-to-commission-list.get.ts),
  // the same query the dashboard "Offene Aufträge" card and the commissioning modal already use.
  // It already applies the iscommissioned/isactive/movementtype/docstatus + fulfillment-order
  // filter server-side, so there's no client-side re-filtering needed here anymore.
  const fetchShipmentList = async (): Promise<any[]> => {
    const res: any = await $fetch('/api/inouts/open-to-commission-list', {
      headers: useRequestHeaders(['cookie'])
    })
    return res?.records || []
  }

  // Line items for the barcode-scan search (searchProductInOpenShipments in
  // integrations/commission.vue), fetched in ONE call for every shipment at once.
  // M_Product_ID here is a to-one FK expand on the TOP-LEVEL m_inoutline list —
  // not a child expand under m_inout — so it doesn't hit the synchronized
  // DefaultQueryConverter path that made the old $expand=m_inoutline($expand=m_product_id)
  // under m_inout expensive (see the "iDempiere REST load rules" recipe).
  const fetchLinesByInoutId = async (inoutIds: number[]): Promise<Record<number, any[]>> => {
    const linesByInoutId: Record<number, any[]> = {}
    if (inoutIds.length === 0) return linesByInoutId

    const filter = string.urlEncode(`M_InOut_ID in (${inoutIds.join(',')})`)
    const res: any = await $fetch(
      `/api/filters/m_inoutline/${filter}&$expand=M_Product_ID&$top=3000`,
      { headers: useRequestHeaders(['cookie']) }
    )

    for (const line of (res?.records || [])) {
      const inoutId = line?.M_InOut_ID?.id ?? line?.m_inout_id?.id ?? line?.M_InOut_ID ?? line?.m_inout_id
      if (!inoutId) continue
      ;(linesByInoutId[inoutId] ||= []).push(line)
    }
    return linesByInoutId
  }

  // Main fetch function
  const fetchOpenShipments = async () => {
    isLoading.value = true
    error.value = null

    try {
      const records = await fetchShipmentList()
      const linesByInoutId = await fetchLinesByInoutId(records.map((r: any) => r.id))

      openShipments.value = records.map((r: any) => ({
        id: r.id,
        DocumentNo: r.documentNo,
        MovementDate: r.movementDate,
        POReference: r.poReference,
        totalQty: r.totalQty,
        orderNo: r.orderNo,
        orderId: r.orderId,
        AD_Org_ID: { Name: r.orgName, identifier: r.orgName },
        C_BPartner_ID: { identifier: r.partnerName },
        C_BPartner_Location_ID: r.locationName ? { Name: r.locationName, identifier: r.locationName } : null,
        M_Shipper_ID: r.shipperName ? { identifier: r.shipperName } : null,
        m_inoutline: linesByInoutId[r.id] || []
      }))
      lastFetched.value = new Date()
    } catch (err: any) {
      console.error('Error fetching open shipments:', err)
      error.value = err?.message || 'Failed to fetch open shipments'
    } finally {
      isLoading.value = false
    }
  }

  // Refresh data (for manual refresh or after commission)
  const refresh = () => {
    return fetchOpenShipments()
  }

  // Remove a shipment from the list (e.g., after it's been commissioned)
  const removeShipment = (shipmentId: number) => {
    openShipments.value = openShipments.value.filter(s => s.id !== shipmentId)
  }

  return {
    openShipments,
    isLoading,
    error,
    lastFetched,
    fetchOpenShipments,
    refresh,
    removeShipment
  }
}
