import mongoose from 'mongoose';
import Decimal from 'decimal.js';

import { findCollateralsWithSheets } from '../../db/collaterals.db';
import { ECollaterals } from '../../enums/collaterals.enum';
import { TQueryParams } from '../../models/QueryResult.model';
import { addHeaderToData } from '../../helpers/excel.helper';
import { getSKUUnitCostForAllDates } from '../../db/inventories.db';

export const getUnitCostDifferenceFull = async (params: TQueryParams) => {
  const data = await getUnitCostDifference(params);
  const header = getUnitCostDifferenceHeader();
  return addHeaderToData(header, data);
};

export const getUnitCostDifference = async (params: TQueryParams) => {
  const { borrowerId } = params;
  const bbcGroups = await findCollateralsWithSheets(borrowerId.toString(), [ECollaterals.INVENTORY]);
  const sheetIds = bbcGroups.reduce((acc, bbcGroup) => [...acc, ...bbcGroup.sheets.map((sheet) => new mongoose.Types.ObjectId(sheet._id))], []);
  const data = await getSKUUnitCostForAllDates(sheetIds);
  const mappedData = data.map((i) => {
    const difference = new Decimal(i.currentCost).sub(i.minCost.minCost).toDP(4).toNumber();
    return {
      SKU: i._id,
      CURRENT_UNIT_COST: i.currentCost,
      LOWEST_UNIT_COST: i.minCost.minCost,
      LOWEST_UNIT_COST_DATE: i.minCost.bbcDate,
      DIFFERENCE: difference,
      CURRENT_QTY: i.qty,
      VALUE_CHANGE: new Decimal(i.qty).mul(difference).toNumber(),
    };
  });
  return mappedData
    .filter((i) => i.DIFFERENCE > 0 || i.VALUE_CHANGE > 0)
    .sort((a, b) => a.VALUE_CHANGE > b.VALUE_CHANGE ? -1 : 0);
};

const getUnitCostDifferenceHeader = () => {
  return {
    SKU: 'SKU',
    CURRENT_QTY: 'qty',
    CURRENT_UNIT_COST: 'Current unit cost',
    LOWEST_UNIT_COST: 'Lowest unit cost',
    LOWEST_UNIT_COST_DATE: 'Lowest BBC date',
    DIFFERENCE: 'Difference',
    VALUE_CHANGE: 'Value change',
  };
};
