import { string, date } from 'alga-js'
import refreshTokenHelper from "../../../utils/refreshTokenHelper"
import forceLogoutHelper from "../../../utils/forceLogoutHelper"
import errorHandlingHelper from "../../../utils/errorHandlingHelper"
import fetchHelper from "../../../utils/fetchHelper"

const getMarketplaceKey = (item: any): string => {
  if (item?.ebay_order_id) return 'ebay'
  if (item?.shopify_order_id) return 'shopify'
  if (item?.shopware6_order_id) return 'shopware6'
  if (item?.amazon_order_id) return 'amazon'
  if (item?.plentyone_order_id) return 'plentyone'
  if (item?.jtl_order_id) return 'jtl-ffn'
  if (item?.xentral_order_id) return 'xentral'
  const os = item?.C_OrderSource_ID
  if (!os) return ''
  const mp = os.Marketplace
  if (typeof mp === 'object' && mp?.identifier) return mp.identifier
  if (typeof mp === 'string') return mp
  const name = (os.Name || os.identifier || '').toLowerCase()
  if (name.includes('ebay')) return 'ebay'
  if (name.includes('shopify')) return 'shopify'
  if (name.includes('amazon')) return 'amazon'
  if (name.includes('shopware')) return 'shopware6'
  if (name.includes('plentyone') || name.includes('plenty')) return 'plentyone'
  if (name.includes('jtl')) return 'jtl-ffn'
  if (name.includes('xentral')) return 'xentral'
  if (name.includes('temu')) return 'temu'
  return ''
}

const idempiereFilterName = (key: string) => {
  let newFilterName = ''
  if(key == 'marketplaceKey') {
    newFilterName = 'C_OrderSource_ID.Marketplace'
  } else if(key == 'id') {
    // grid 'id' column → real PK column ('id' is a JSON convenience field,
    // not a queryable iDempiere column)
    newFilterName = 'c_order_id'
  } else if(key == 'uid') {
    newFilterName = 'C_Order_UU'
  } else if(key == 'isActive') {
    newFilterName = 'IsActive'
  } else if(key == 'documentNo') {
    newFilterName = 'DocumentNo'
  } else if(key == 'description') {
    newFilterName = 'Description'
  } else if(key == 'isApproved') {
    newFilterName = 'IsApproved'
  } else if(key == 'isCreditApproved') {
    newFilterName = 'IsCreditApproved'
  } else if(key == 'isDelivered') {
    newFilterName = 'IsDelivered'
  } else if(key == 'isInvoiced') {
    newFilterName = 'IsInvoiced'
  } else if(key == 'isPrinted') {
    newFilterName = 'IsPrinted'
  } else if(key == 'isTransferred') {
    newFilterName = 'IsTransferred'
  } else if(key == 'dateOrdered') {
    newFilterName = 'DateOrdered'
  } else if(key == 'dateCreated') {
    newFilterName = 'Created'
  } else if(key == 'datePromised') {
    newFilterName = 'DatePromised'
  } else if(key == 'dateAcct') {
    newFilterName = 'DateAcct'
  } else if(key == 'freightAmt') {
    newFilterName = 'FreightAmt'
  } else if(key == 'totalLines') {
    newFilterName = 'TotalLines'
  } else if(key == 'grandTotal') {
    newFilterName = 'GrandTotal'
  } else if(key == 'chargeAmt') {
    newFilterName = 'ChargeAmt'
  } else if(key == 'processed') {
    newFilterName = 'Processed'
  } else if(key == 'isSOTrx') {
    newFilterName = 'IsSOTrx'
  } else if(key == 'isDiscountPrinted') {
    newFilterName = 'IsDiscountPrinted'
  } else if(key == 'isTaxIncluded') {
    newFilterName = 'IsTaxIncluded'
  } else if(key == 'isSelected') {
    newFilterName = 'IsSelected'
  } else if(key == 'sendEMail') {
    newFilterName = 'SendEMail'
  } else if(key == 'isSelfService') {
    newFilterName = 'IsSelfService'
  } else if(key == 'isDropShip') {
    newFilterName = 'IsDropShip'
  } else if(key == 'processedOn') {
    newFilterName = 'ProcessedOn'
  } else if(key == 'isPayScheduleValid') {
    newFilterName = 'IsPayScheduleValid'
  } else if(key == 'isPriviledgedRate') {
    newFilterName = 'IsPriviledgedRate'
  } else if(key == 'docStatus') {
    newFilterName = 'DocStatus'
  } else if(key == 'docType') {
    newFilterName = 'C_DocType_ID'
  } else if(key == 'docTypeTarget') {
    newFilterName = 'C_DocTypeTarget_ID'
  } else if(key == 'salesRep') {
    newFilterName = 'SalesRep_ID'
  } else if(key == 'paymentTerm') {
    newFilterName = 'C_PaymentTerm_ID'
  } else if(key == 'currency') {
    newFilterName = 'C_Currency_ID'
  } else if(key == 'invoiceRule') {
    newFilterName = 'InvoiceRule'
  } else if(key == 'deliveryViaRule') {
    newFilterName = 'DeliveryViaRule'
  } else if(key == 'deliveryRule') {
    newFilterName = 'DeliveryRule'
  } else if(key == 'priorityRule') {
    newFilterName = 'PriorityRule'
  } else if(key == 'freightCostRule') {
    newFilterName = 'FreightCostRule'
  } else if(key == 'paymentRule') {
    newFilterName = 'PaymentRule'
  } else if(key == 'warehouse') {
    newFilterName = 'M_Warehouse_ID'
  } else if(key == 'priceList') {
    newFilterName = 'M_PriceList_ID'
  } else if(key == 'partner') {
    newFilterName = 'C_BPartner_ID'
  } else if(key == 'partnerLocation') {
    newFilterName = 'C_BPartner_Location_ID'
  } else if(key == 'user') {
    newFilterName = 'AD_User_ID'
  } else if(key == 'cashLine') {
    newFilterName = 'C_CashLine_ID'
  } else if(key == 'billPartner') {
    newFilterName = 'Bill_BPartner_ID'
  } else if(key == 'billPartnerLocation') {
    newFilterName = 'Bill_Location_ID'
  } else if(key == 'billUser') {
    newFilterName = 'Bill_User_ID'
  } else if(key == 'organization') {
    newFilterName = 'AD_Org_ID'
  } else if(key == 'orderSource') {
    newFilterName = 'C_OrderSource_ID'
  } else if(key == 'externalorderId') {
    newFilterName = 'ExternalOrderId'
  } else if(key == 'shopware6_order_id') {
    newFilterName = 'shopware6_order_id'
  } else if(key == 'country') {
    newFilterName = 'C_BPartner_Location_ID.C_Location_ID.C_Country_ID'
  }
  return newFilterName
}

const filterHandler = (filterModel: any) => {
  // Skip unmapped columns and empty fragments — a nameless fragment
  // (' eq x' / 'contains(,x)') crashes the iDempiere query parser.
  const parts: string[] = []
  for(const key of Object.keys(filterModel)) {
    const filterName = idempiereFilterName(key)
    if(!filterName) continue
    const item = filterModel[key]
    let part = ''
    if(item.filterType == 'text') {
      part = textFilterHandler(filterName, item)
    } else if(item.filterType == 'number') {
      part = numberFilterHandler(filterName, item)
    } else if(item.filterType == 'date' && item.dateFrom) {
      part = `${filterName} eq ${item.dateFrom}`
    }
    if(part) parts.push(part)
  }
  return parts.length >= 1 ? ` AND (${parts.join(' AND ')})` : ''
}

const numberFilterHandler = (key: string, item: any) => {
  let newNumberFilter = ''
  if(item.type == 'equals') {
    newNumberFilter = `${key} eq ${item.filter}`
  } else if(item.type == 'notEqual') {
    newNumberFilter = `${key} neq ${item.filter}`
  } else if(item.type == 'greaterThan') {
    newNumberFilter = `${key} gt ${item.filter}`
  } else if(item.type == 'greaterThanOrEqual') {
    newNumberFilter = `${key} ge ${item.filter}`
  } else if(item.type == 'lessThan') {
    newNumberFilter = `${key} lt ${item.filter}`
  } else if(item.type == 'lessThanOrEqual') {
    newNumberFilter = `${key} le ${item.filter}`
  } else if(item.type == 'inRange') {
    newNumberFilter = `${key} ge ${item.filter} AND ${key} le ${item.filterTo}`
  }
  return newNumberFilter
}

const textFilterHandler = (key: string, item: any) => {
  let newTextFilter = ''
  if(item.type == 'equals') {
    newTextFilter = `${key} eq ${item.filter}`
  } else if(item.type == 'notEqual') {
    newTextFilter = `${key} neq ${item.filter}`
  } else if(item.type == 'contains') {
    newTextFilter = `contains(${key},${item.filter.replaceAll('%', '')})`
  } else if(item.type == 'notContains') {
    newTextFilter = `not contains(${key},${item.filter.replaceAll('%', '')})`
  } else if(item.type == 'startsWith') {
    newTextFilter = `startswith(${key},'${item.filter}')`
  } else if(item.type == 'endsWith') {
    newTextFilter = `endswith(${key},'${item.filter}')`
  }
  return newTextFilter
}

const handleFunc = async (event: any, authToken: any = null) => {
  let data: any = {
    rows: [], 
    lastRow: 0
  }
  const config = useRuntimeConfig()
  const token = authToken ?? await getTokenHelper(event)
  const organizationId = getCookie(event, 'organizationId')
  const body = await readBody(event)

  const startRow = body.startRow
  const endRow = body.endRow
  const pageSize = (endRow - startRow) + 1

  const res: any = await fetchHelper(event, `views/C_Order_NotFulfilled_5day?$filter=${string.urlEncode('(isSOTrx eq true AND isActive eq true OR isActive eq false)'+filterHandler(body.filterModel))}&$expand=c_ordersource_id,c_bpartner_location_id,bill_location_id,c_orderline,m_inout&$orderby=${string.urlEncode('c_order_id desc')}&$top=${pageSize}&$skip=${startRow}`, 'GET', token, null)
  if(res) {
    const country: any = await fetchHelper(event, `models/c_country?$filter=${string.urlEncode('isActive eq true OR isActive eq false')}&$orderby=${string.urlEncode('c_country_id desc')}`, 'GET', token, null)

    let allRecords = res['records']?.map((item: any) => {
      return {
        marketplaceKey: getMarketplaceKey(item),
        id: item.id,
        uid: item.uid,
        isActive: item.isActive,
        documentNo: item.documentNo,
        description: item.description,
        isApproved: item.isApproved,
        isCreditApproved: item.isCreditApproved,
        isDelivered: item.isDelivered,
        isInvoiced: item.isInvoiced,
        isPrinted: item.isPrinted,
        isTransferred: item.isTransferred,
        dateOrdered: item.dateOrdered,
        dateCreated: item.created,
        datePromised: item.datePromised,
        dateAcct: item.dateAcct,
        freightAmt: item.freightAmt,
        totalLines: item.totalLines,
        grandTotal: item.grandTotal,
        chargeAmt: item.chargeAmt,
        processed: item.processed,
        isSOTrx: item.isSOTrx,
        isDiscountPrinted: item.isDiscountPrinted,
        isTaxIncluded: item.isTaxIncluded,
        isSelected: item.isSelected,
        sendEMail: item.sendEMail,
        isSelfService: item.isSelfService,
        isDropShip: item.isDropShip,
        processedOn: item.processedOn,
        isPayScheduleValid: item.isPayScheduleValid,
        isPriviledgedRate: item.isPriviledgedRate,
        docStatus: item.DocStatus?.identifier || '',
        docStatusId: item.DocStatus?.id || '',
        docType: item.C_DocType_ID?.identifier || '',
        docTypeId: item.C_DocType_ID?.id || '',
        docTypeTarget: item.C_DocTypeTarget_ID?.identifier || '',
        docTypeTargetId: item.C_DocTypeTarget_ID?.id || '',
        salesRep: item.SalesRep_ID?.identifier || '',
        salesRepId: item.SalesRep_ID?.id || '',
        paymentTerm: item.C_PaymentTerm_ID?.identifier || '',
        paymentTermId: item.C_PaymentTerm_ID?.id || '',
        currency: item.C_Currency_ID?.identifier || '',
        currencyId: item.C_Currency_ID?.id || '',
        invoiceRule: item.InvoiceRule?.identifier || '',
        invoiceRuleId: item.InvoiceRule?.id || '',
        deliveryViaRule: item.DeliveryViaRule?.identifier || '',
        deliveryViaRuleId: item.DeliveryViaRule?.id || '',
        deliveryRule: item.DeliveryRule?.identifier || '',
        deliveryRuleId: item.DeliveryRule?.id || '',
        priorityRule: item.PriorityRule?.identifier || '',
        priorityRuleId: item.PriorityRule?.id || '',
        freightCostRule: item.FreightCostRule?.identifier || '',
        freightCostRuleId: item.FreightCostRule?.id || '',
        paymentRule: item.PaymentRule?.identifier || '',
        paymentRuleId: item.PaymentRule?.id || '',
        warehouse: item.M_Warehouse_ID?.identifier || '',
        warehouseId: item.M_Warehouse_ID?.id || '',
        priceList: item.M_PriceList_ID?.identifier || '',
        priceListId: item.M_PriceList_ID?.id || '',
        partner: item.C_BPartner_ID?.identifier || item.C_BPartner_ID?.Name || '',
        partnerId: item.C_BPartner_ID?.id || '',
        partnerLocation: item.C_BPartner_Location_ID || {},
        partnerLocationId: item.C_BPartner_Location_ID?.id || '',
        partnerLocationName: item.C_BPartner_Location_ID?.Name || '',
        user: item.AD_User_ID?.identifier || '',
        userId: item.AD_User_ID?.id || '',
        cashLine: item.C_CashLine_ID?.identifier || '',
        cashLineId: item.C_CashLine_ID?.id || '',
        billPartner: item.Bill_BPartner_ID?.identifier || '',
        billPartnerId: item.Bill_BPartner_ID?.id || '',
        billPartnerLocation: item.Bill_Location_ID || {},
        billPartnerLocationId: item.Bill_Location_ID?.id || '',
        billUser: item.Bill_User_ID?.identifier || '',
        billUserId: item.Bill_User_ID?.id || '',
        organization: item.AD_Org_ID?.identifier || '',
        organizationId: item.AD_Org_ID?.id || '',
        client: item.AD_Client_ID?.identifier || '',
        clientId: item.AD_Client_ID?.id || '',
        orderSource: item.C_OrderSource_ID?.identifier || '',
        orderSourceId: item.C_OrderSource_ID?.id  || '',
        orderSourceData: item.C_OrderSource_ID || '',
        externalorderId: item.ExternalOrderId  || '',
        shopware6_order_id: item.shopware6_order_id || '',
        shopify_order_id: item.shopify_order_id || '',
        orderLines: item.c_orderline || [],
        country: item.C_BPartner_Location_ID?.C_Location_ID?.C_Country_ID?.identifier || '',
        countryId: item.C_BPartner_Location_ID?.C_Location_ID?.C_Country_ID?.id || '',
        countries: country?.records || [],
        location: item.C_BPartner_Location_ID?.C_Location_ID || {},
        locationStreet: item.C_BPartner_Location_ID?.C_Location_ID?.Address1 || '',
        locationStreet2: item.C_BPartner_Location_ID?.C_Location_ID?.Address2 || '',
        locationZipCode: item.C_BPartner_Location_ID?.C_Location_ID?.Postal || '',
        locationCity: item.C_BPartner_Location_ID?.C_Location_ID?.City || '',
        minout: item.m_inout || []
      }
    }) || []

    data.rows = allRecords
    data.lastRow = res['row-count'] || 0
    data.filterModel = filterHandler(body.filterModel) || ''
  }

  return data
}

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) {
      //@ts-ignore
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      //forceLogoutHelper(event, data)
    }
  }

  return data
})