import { string } from 'alga-js'
import refreshTokenHelper from "../../utils/refreshTokenHelper"
import errorHandlingHelper from "../../utils/errorHandlingHelper"

/**
 * Lightweight endpoint that returns only the count of unpaid invoices
 * for the fulfillment customer linked to the current organization.
 */
const handleFunc = async (event: any, authToken: any = null) => {
  const config = useRuntimeConfig()
  const serviceToken = config.api.idempieretoken
  const organizationId = getCookie(event, 'logship_organization_id')

  if (!organizationId || !serviceToken) {
    return { count: 0 }
  }

  try {
    // Get the org's business partner ID
    const orgFilter = `AD_Org_ID eq ${organizationId}`
    const orgUrl = `${config.api.url}/models/ad_org?$filter=${string.urlEncode(orgFilter)}&$select=C_BPartner_ID`

    const orgRes: any = await $fetch(orgUrl, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
        Authorization: 'Bearer ' + serviceToken
      }
    })

    const bpartnerId = orgRes?.records?.[0]?.C_BPartner_ID?.id
    if (!bpartnerId) {
      return { count: 0 }
    }

    // Fetch only unpaid invoices (IsPaid = N) with CO or CL status
    const bpartnerFilter = `C_BPartner_ID eq ${bpartnerId} and IsPaid eq 'N' and (DocStatus eq 'CO' or DocStatus eq 'CL')`
    const invoiceUrl = `${config.api.url}/models/C_Invoice?$filter=${string.urlEncode(bpartnerFilter)}&$select=C_Invoice_ID,IsPaid,GrandTotal&$orderby=C_Invoice_ID desc`

    const res: any = await $fetch(invoiceUrl, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
        Authorization: 'Bearer ' + serviceToken
      }
    })

    const invoices = res?.records || []
    if (invoices.length === 0) {
      return { count: 0 }
    }

    // Check allocations to exclude fully paid invoices (IsPaid might not be updated yet)
    const invoiceIds = invoices.map((inv: any) => inv.id)
    let allocationSums: Record<number, number> = {}

    try {
      const allocUrl = `${config.api.url}/models/c_allocationline?$filter=${string.urlEncode(`C_Invoice_ID in (${invoiceIds.join(',')})`)}&$select=C_Invoice_ID,Amount,C_Payment_ID&$expand=C_Payment_ID($select=DocStatus)`
      const allocRes: any = await $fetch(allocUrl, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
          Authorization: 'Bearer ' + serviceToken
        }
      })

      if (allocRes?.records?.length > 0) {
        for (const alloc of allocRes.records) {
          const invoiceId = alloc.C_Invoice_ID?.id
          const paymentDocStatus = alloc.C_Payment_ID?.DocStatus?.id || alloc.C_Payment_ID?.DocStatus || ''
          if (invoiceId && paymentDocStatus === 'CO') {
            allocationSums[invoiceId] = (allocationSums[invoiceId] || 0) + (alloc.Amount || 0)
          }
        }
      }
    } catch (err) {
      // If allocations fail, count all as unpaid
    }

    // Count invoices where paid amount < grand total (use abs for credit memos)
    let unpaidCount = 0
    for (const invoice of invoices) {
      const paidAmt = Math.abs(allocationSums[invoice.id] || 0)
      const grandTotal = Math.abs(invoice.GrandTotal || 0)
      if (paidAmt < grandTotal) {
        unpaidCount++
      }
    }

    return { count: unpaidCount }
  } catch (err) {
    console.warn('Could not fetch unpaid invoice count:', err)
    return { count: 0 }
  }
}

export default defineEventHandler(async (event) => {
  let data: any = {}

  try {
    data = await handleFunc(event)
  } catch (err: any) {
    try {
      let authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
    }
  }

  return data
})
