import { IBorrowerGroupWithId } from '../interfaces/group.interface';
import { ICustomerGroupDocument } from '../models/CustomerGroup.model';
import { groupsMap } from '../db/groups.db';

import MappedGroup, { IMappedGroup } from '../models/MappedGroup.model';

export class GroupsService {
  async createBorrowerGroups(borrowerId: string, groupType: string, groups: IBorrowerGroupWithId[]) {
    const groupIds = groups.map((group) => group._id);
    const allExistedGroups: ICustomerGroupDocument[] = await groupsMap[groupType].Model.find({ borrowerId }).lean();
    await Promise.all(allExistedGroups.map(async (group) => {
      if (!groupIds.includes(group._id.toString())) {
        await groupsMap[groupType].Model.findByIdAndDelete(group._id.toString());
      }
    }))
    await Promise.all(groups.map(async (group) => {
      if (!group._id) {
        const newGroup = new groupsMap[groupType].Model(group);
        await newGroup.save();
      } else {
        await groupsMap[groupType].Model.findByIdAndUpdate(group._id, group);
      }
    }));
  }

  async getBorrowerGroups(borrowerId: string, relationshipGroups: string | string[]) {
    if (typeof relationshipGroups == 'string') {
      relationshipGroups = [relationshipGroups];
    }
    const allCustomerGroups = await Promise.all(relationshipGroups.map(async (groupName) => {
      const groups = await groupsMap[groupName].Model.find({ borrowerId }).sort({ 'createdAt': 1 });
      return { [groupName]: groups };
    }))
    return allCustomerGroups.reduce((acc, group) => {
      return { ...acc, ...group };
    }, {});
  }

  async createMappedGroups(borrowerId: string, groupType: string, groups: IMappedGroup[]) {
    await MappedGroup.deleteMany({ borrowerId, groupType });
    await Promise.all(groups.map(async (group) => {
      const newMappedGroup = new MappedGroup({
        borrowerId,
        group1: group.group1,
        group2: group.group2,
        groupType: groupType,
      });
      await newMappedGroup.save();
    }));
  }

  async getMappedGroups(borrowerId: string, groupTypes: string | string[]) {
    if (typeof groupTypes == 'string') {
      groupTypes = [groupTypes];
    }
    const allMappedGroups = await Promise.all(groupTypes.map(async (groupType) => {
      const groups = await MappedGroup.find({ borrowerId, groupType });
      return { [groupType]: groups };
    }))
    return allMappedGroups.reduce((acc, group) => {
      return { ...acc, ...group };
    }, {});
  }
}
