import mongoose from 'mongoose';

import { ECollaterals } from '../enums/collaterals.enum';
import { BBCSheetModel, IBBCSheet, IBBCSheetDoc } from '../models/BBCSheet.model';
import { MODEL_NAMES } from '../models/_models';

export const getBBCSheetsByType = async (bbcDateIds: string[], collateralType: ECollaterals) => {
  return BBCSheetModel.aggregate<IBBCSheetDoc>([
    {
      $match: {
        bbcDateId: { $in: bbcDateIds.map((id) => new mongoose.Types.ObjectId(id)) },
        dataType: collateralType,
      },
    },
    {
      $sort: { updatedAt: 1 },
    },
  ]);
};

export const getBBCSheetsByTypeGroupedByBBC = async (bbcDateIds: string[], collateralType: ECollaterals) => {
  return BBCSheetModel.aggregate<{ _id: mongoose.Types.ObjectId, sheets: IBBCSheetDoc[] }>([
    {
      $match: {
        bbcDateId: { $in: bbcDateIds.map((id) => new mongoose.Types.ObjectId(id)) },
        dataType: collateralType,
      },
    },
    {
      $sort: { updatedAt: 1 },
    },
    {
      $group: {
        '_id': '$bbcDateId',
        'sheets': {
          $addToSet: {
            '_id': '$_id',
            'bbcDateId': '$bbcDateId',
            'dataType': '$dataType',
            'fileName': '$fileName',
            'sheetName': '$sheetName',
            'createdAt': '$createdAt',
            'updatedAt': '$updatedAt',
            '__v': '$__v',
          },
        },
      },
    },
  ]);
};

export const getUniqueDates = async (borrowerId: string, limit: number, collateral: ECollaterals) => {
  return BBCSheetModel.aggregate<{ bbcDate: Date, ids: mongoose.Types.ObjectId[] }>([
    {
      $match: {
        'dataType': collateral,
      },
    },
    {
      $lookup: {
        from: MODEL_NAMES.BBCDates,
        localField: 'bbcDateId',
        foreignField: '_id',
        as: 'bbc',
      },
    },
    {
      $unwind: {
        path: '$bbc',
      },
    },
    {
      $match: {
        'bbc.borrowerId': new mongoose.Types.ObjectId(borrowerId),
      },
    },
    {
      $project: {
        '_id': 1,
        'bbcDate': '$bbc.bbcDate',
      },
    },
    {
      $group: {
        '_id': '$bbcDate',
        'ids': {
          $addToSet: '$_id',
        },
      },
    },
    {
      $sort: {
        '_id': -1,
      },
    },
    {
      $limit: limit,
    },
    {
      $project: {
        'bbcDate': '$_id',
        '_id': 0,
        'ids': 1,
      },
    },
  ]);
};

export const getUniqueDatesForPeriod = async (borrowerId: string, collateral: ECollaterals, startDate: Date, endDate: Date) => {
  return BBCSheetModel.aggregate<{ _id: mongoose.Types.ObjectId; bbcDate: Date; ids: mongoose.Types.ObjectId[] }>([
    {
      $match: {
        'dataType': collateral,
      },
    },
    {
      $lookup: {
        from: MODEL_NAMES.BBCDates,
        localField: 'bbcDateId',
        foreignField: '_id',
        as: 'bbc',
      },
    },
    {
      $unwind: {
        path: '$bbc',
      },
    },
    {
      $match: {
        $and: [
          { 'bbc.borrowerId': new mongoose.Types.ObjectId(borrowerId) },
          { 'bbc.bbcDate': { $gte: startDate } },
          { 'bbc.bbcDate': { $lte: endDate } },
        ],
      },
    },
    {
      $project: {
        '_id': 1,
        'bbcDate': '$bbc.bbcDate',
        'bbcDateId': '$bbc._id',
      },
    },
    {
      $group: {
        '_id': '$bbcDateId',
        'bbcDate': { $first: '$bbcDate' },
        'ids': {
          $addToSet: '$_id',
        },
      },
    },
    {
      $sort: {
        'bbcDate': 1,
      },
    },
  ]);
};

export const createBBCSheet = async (bbcDateId: string, dataType: 'INVENTORY' | 'RECEIVABLE') => {
  const newSheet: Partial<IBBCSheet> = {
    bbcDateId: new mongoose.Types.ObjectId(bbcDateId),
    comment: 'manual',
    dataType,
    fileName: 'manual.xlsx',
    sheetName: 'manual',
  };
  const newBBCSheet = new BBCSheetModel(newSheet);
  return newBBCSheet.save();
};
