import { EntityManager, getRepository } from 'typeorm'

import { Bizplace } from '@things-factory/biz-base'
import { ListParam } from '@things-factory/shell'

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

      await inventoryHistorySummaryReportQuery(_, params, context)

      const total: any = await tx.query(`select count(*) from temp_inventory_summary`)

      const result: any = await tx.query(
        ` 
        select * from temp_inventory_summary ORDER BY initial_date OFFSET $1 LIMIT $2
      `,
        [(params.pagination.page - 1) * params.pagination.limit, params.pagination.limit]
      )

      let items = result.map(itm => {
        return {
          ...itm,
          batchId: itm.batch_id,
          packingType: itm.packing_type,
          openingQty: itm.opening_qty,
          adjustmentQty: itm.adjustment_qty,
          closingQty: itm.closing_qty,
          totalInQty: itm.total_in_qty,
          totalOutQty: itm.total_out_qty,
          totalReturnQty: itm.total_return_qty,
          initialQty: itm.initial_qty,
          initialDate: itm.initial_date,
          product: {
            id: itm.product_id,
            sku: itm.product_sku,
            name: itm.product_name,
            description: itm.product_description
          }
        }
      })

      return { items, total: total[0].count }
    } catch (error) {
      throw error
    }
  }
}

export async function inventoryHistorySummaryReportQuery(_: any, params: ListParam, context: any): Promise<void> {
  try {
    const { tx }: { tx: EntityManager } = context.state

    let balanceOnlyFilter = params.filters.find(data => data.name === 'balanceOnly')

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

    let fromDate = params.filters.find(data => data.name === 'fromDate')
    let toDate = params.filters.find(data => data.name === 'toDate')

    if (!bizplaceFilter || !fromDate || !toDate) throw 'Invalid input'

    const bizplace: Bizplace = await getRepository(Bizplace).findOne({
      id: bizplaceFilter.value
    })

    let balanceOnlyQuery = ''
    if (balanceOnlyFilter && balanceOnlyFilter.value) {
      balanceOnlyQuery = 'and (opening_qty + adjustment_qty + total_in_qty + total_out_qty + total_return_qty) > 0 '
    }

    await tx.query(
      `
      create temp table temp_inv_history on commit drop as (
        select i2.pallet_id, ih.product_id::uuid, ih.packing_type, ih.batch_id,
        ih.id as inventory_history_id, ih.seq, ih.status, ih.transaction_type, ih.qty, ih.opening_qty, ih.created_at,
        ih.ref_order_id::uuid as ref_order_id
        from inventories i2
        inner join reduced_inventory_histories ih on ih.pallet_id = i2.pallet_id and ih.domain_id = i2.domain_id
        where
        i2.domain_id = $1
        and i2.bizplace_id = $2
        and ih.created_at <= $3
      )
    `,
      [context.state.domain.id, bizplace.id, toDate.value]
    )

    await tx.query(
      `
      create temp table temp_inventory_summary on commit drop as (
        select src.*,
        opening_qty + adjustment_qty + total_in_qty + total_out_qty + total_return_qty as closing_qty,
        prd.name as product_name, prd.sku as product_sku, prd.description as product_description 
        from (
          select ih.batch_id, ih.packing_type,
          min(ih.created_at) as initial_date,
          sum(case when (ih.transaction_type = 'UNLOADING' or ih.transaction_type = 'NEW') and rtn.id is null then qty else 0 end) as initial_qty,
          sum(case when ih.created_at > $1 and ih.transaction_type = 'ADJUSTMENT' then ih.qty else 0 end) as adjustment_qty,
          sum(case when ih.created_at < $1 then ih.qty else 0 end) as opening_qty,
          sum(case when ih.created_at > $1 then case when ih.qty > 0 and ih.transaction_type <> 'ADJUSTMENT' and ih.transaction_type <> 'RETURN' and rtn.id is null then ih.qty else 0 end else 0 end) as total_in_qty,
          sum(case when ih.created_at > $1 then case when (ih.qty < 0 and ih.transaction_type <> 'ADJUSTMENT')  or ih.transaction_type = 'RETURN' then ih.qty else 0 end else 0 end) as total_out_qty,
          ih.product_id,
          sum(case when rtn.id is not null and ih.transaction_type <> 'ADJUSTMENT' and ih.created_at > $1 then qty else 0 end) as total_return_qty
          from temp_inv_history ih
          left join return_orders rtn on rtn.id = ih.ref_order_id
          group by ih.batch_id, ih.product_id, ih.packing_type
          order by batch_id
        ) src
        inner join products prd on prd.id = src.product_id
        where (opening_qty > 0 or total_in_qty > 0 or adjustment_qty > 0)
        ${balanceOnlyQuery}
      )
    `,
      [fromDate.value]
    )
  } catch (error) {
    throw error
  }
}
