import { getRepository, SelectQueryBuilder, EntityManager } from 'typeorm'

import { User } from '@things-factory/auth-base'
import { getPermittedBizplaceIds } from '@things-factory/biz-base'
import { buildQuery, Domain, ListParam } from '@things-factory/shell'

export const unitInboundedOutboundedResolver = {
  async unitInboundedOutbounded(_: any, params: ListParam, context: any) {
    const { domain, user, tx }: { domain: Domain; user: User; tx: EntityManager } = context.state
    const bizplaceId: string = params.filters.find((filter: any) => filter.name === 'bizplace')?.value || 'ALL'
    const fromDate: string = params.filters.find((filter: any) => filter.name === 'createdAt1')?.value
    const toDate: string = params.filters.find((filter: any) => filter.name === 'createdAt2')?.value
    const v4 = new RegExp(/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i)
    let bizplaceIds: string

    if (bizplaceId && (bizplaceId == 'ALL' || bizplaceId.match(v4))) {
      let bizplaces: string[] =
        bizplaceId && bizplaceId != 'ALL' ? [bizplaceId] : await getPermittedBizplaceIds(domain, user)
      bizplaceIds = bizplaces
        .map(bizplace => {
          return "'" + bizplace?.trim() + "'"
        })
        .join(',')
    } else throw new Error('invalid bizplaceId')

    const orderStatus: { status: string; count: number }[] = await tx.query(
      `
        WITH cte_unit ("status", "count", "type") AS (
          SELECT 'INBOUNDED' AS status, 0 AS "count", 'inbound' AS "type"
          UNION
          SELECT 'OUTBOUNDED' AS status, 0 AS "count", 'outbound' AS "type"
        ) SELECT u."status", coalesce(src."count", u."count") AS "count", u."type"
        FROM cte_unit u
        LEFT JOIN (
          SELECT "status", SUM("count") AS count, "type" FROM (
            SELECT 'INBOUNDED' AS "status", SUM(coalesce(op.actual_pack_qty, op.pack_qty)) as "count", 'inbound' as "type" FROM order_products op
            INNER JOIN arrival_notices an ON an.id = op.arrival_notice_id
            WHERE an."status" in ('PUTTING_AWAY','DONE')
            AND an."domain_id" = $1
            AND an."bizplace_id" IN (${bizplaceIds})
            AND an.created_at BETWEEN '${fromDate}' AND '${toDate}'
            GROUP BY an."status"
            UNION ALL
            SELECT 'OUTBOUNDED' AS "status", SUM(coalesce(oi.release_qty , oi.picked_qty)) as "count", 'outbound' as "type" FROM order_inventories oi
            INNER JOIN release_goods rg on rg.id = oi.release_good_id
            WHERE rg."status" in ('DONE')
            AND rg."domain_id" = $1
            AND rg."bizplace_id" IN (${bizplaceIds})
            AND rg.created_at BETWEEN '${fromDate}' AND '${toDate}'
            GROUP BY rg."status"
          ) AS src
          GROUP BY "status", "type"
        ) src ON src."status" = u."status"
        order by "type", "status"
      `,
      [domain.id]
    )

    return orderStatus
  }
}
