import { onhandInventories } from '@things-factory/warehouse-base'
import { ListParam } from '@things-factory/shell'
import { EntityManager } from 'typeorm'
import { inventoryHistorySummaryReportQuery } from '../custom/elccl/elccl-inventory-history-summary-report'

export const inventoryComparisonList = {
  async inventoryComparisonList(_: any, params: ListParam, context: any) {
    try {
      const { tx }: { tx: EntityManager } = context.state

      let bizplaceFilter = params.filters.find(data => data.name === 'bizplace')

      if (!bizplaceFilter) {
        return
      }

      let toDateFilter = params.filters.find(data => data.name === 'toDate')
      let toDateDate = new Date(toDateFilter.value)
      let fromDate = toDateDate.setDate(toDateDate.getDate() - 1)
      let fromDateISO = new Date(fromDate).toISOString()
      let nonTallyFilter = params.filters.find(data => data.name === 'nonTally').value
      let productFilter = params.filters.find(data => data.name === 'product')

      params.filters.push({
        name: 'fromDate',
        operator: 'eq',
        value: fromDateISO
      })

      params.filters.push(
        { name: 'status', operator: 'notin', value: ['INTRANSIT', 'TERMINATED', 'DELETED'] },
        { name: 'remainOnly', operator: 'eq', value: true },
        { name: 'unlockOnly', operator: 'eq', value: true },
        { name: 'created_at', operator: 'eq', value: toDateFilter.value },
        { name: 'timezoneOffset', operator: 'eq', value: new Date().getTimezoneOffset() },
        { name: 'expiration', operator: 'eq', value: false }
      )

      let productQueryFilter = ``

      if (productFilter) {
        let products = productFilter.value
          .toLowerCase()
          .split(',')
          .map(prod => {
            return "'%" + prod.trim().replace(/'/g, "''") + "%'"
          })
          .join(',')

        productQueryFilter =
          productQueryFilter +
          `
          ${nonTallyFilter ? 'and' : 'where'} (lower(summ.product_name) like any(array[${products}])
          or lower(summ.product_sku) like any(array[${products}]))`
      }

      await Promise.all([
        inventoryHistorySummaryReportQuery(_, params, context),
        onhandInventories(params.filters, params.pagination, params.sortings, [], context, false)
      ])
    
      await tx.query(`
        create temp table tmp_inv_comp on commit drop as (
          select summ."batch_id", summ.product_id, summ.product_name, summ.product_sku, summ.packing_type, summ.closing_qty, coalesce(oh.qty, 0) as "onhand_qty" from temp_inventory_summary summ 
          left join (	
            select "batch_id" as "batch_id", product_id, sum("qty") as qty from tmp_data group by "batch_id", product_id
          ) oh on oh.batch_id = summ.batch_id and oh.product_id = summ.product_id
          ${nonTallyFilter ? 'where coalesce(oh.qty, 0) <> summ.closing_qty' : ''}
          ${productQueryFilter}
        );
      `)

      let sumData = await tx.query(`
        select * from tmp_inv_comp
        offset $1 limit $2
      `, [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit])

      const totalQuery: number = await tx.query(`select count(*) from tmp_inv_comp `)
      
      const total = parseInt(totalQuery[0].count)

      const items: any[] = sumData.map(item => {
        return {
          productName: item.product_name,
          productSku: item.product_sku,
          packingType: item.packing_type,
          closingQty: item.closing_qty,
          remainQty: item.onhand_qty,
          batchId: item.batch_id
        }
      })

      return { items, total }

    } catch (error) {
      throw error
    }
  }
}
