import { IOrganization, IOrganizationLean, Organization } from '../models/Organization.model';
import { BorrowerModel, IBorrowerLean } from '../models/Borrower.model';

import { fieldsToUnset, removeFields } from '../helpers/main.helper';
import { IOrganizationEmail, OrganizationEmail, OrganizationEmailsType } from '../models/OrganizationEmails.model';

const initialOrganizations: (IOrganization & { emails: IOrganizationEmail[] })[] = [
  {
    name: 'GemCap',
    isDefault: false,
    subfolder: 'gemcap',
    emails: [
      { organizationId: null, type: OrganizationEmailsType.SENDER, address: 'compliance@gemcapsolutions.com', title: 'GemCap' },
      { organizationId: null, type: OrganizationEmailsType.PORTFOLIO, address: 'portfolio@gemcapsolutions.com', title: 'GemCap' },
      { organizationId: null, type: OrganizationEmailsType.FINANCIAL, address: 'finance@gemcapsolutions.com', title: 'GemCap Finance Department' },
      { organizationId: null, type: OrganizationEmailsType.HIDDEN_RECIPIENT, address: 'compliance@gemcapsolutions.com', title: 'GemCap' },
    ],
  },
  {
    name: 'Black Feather',
    isDefault: true,
    subfolder: 'black_feather',
    emails: [
      { organizationId: null, type: OrganizationEmailsType.SENDER, address: 'compliance@blackfeatherfunding.com', title: 'Black Feather' },
      { organizationId: null, type: OrganizationEmailsType.PORTFOLIO, address: 'portfolio@blackfeatherfunding.com', title: 'Black Feather' },
      { organizationId: null, type: OrganizationEmailsType.FINANCIAL, address: 'finance@blackfeatherfunding.com', title: 'Black Feather Finance Department' },
      { organizationId: null, type: OrganizationEmailsType.HIDDEN_RECIPIENT, address: 'compliance@blackfeatherfunding.com', title: 'Black Feather' },
    ],
  },
];

export class OrganizationsService {
  async getOrganizations() {
    const organizations = await Organization.find().sort({ name: 1 });
    return organizations.map((i) => removeFields<IOrganization>(i, fieldsToUnset));
  }

  async createInitialOrganizations() {
    await Promise.all(initialOrganizations.map(async (organization) => {
      const updatedOrganization = await Organization.findOneAndUpdate(
        { name: organization.name },
        {
          $setOnInsert: {
            name: organization.name,
            subfolder: organization.subfolder,
            isDefault: organization.isDefault,
          },
        },
        { upsert: true, new: true },
      );
      await Promise.all(organization.emails.map(async (email) => {
        await OrganizationEmail.findOneAndUpdate(
          { type: email.type, organizationId: updatedOrganization._id },
          {
            $setOnInsert: {
              organizationId: updatedOrganization._id,
              type: email.type,
              title: email.title,
              address: email.address,
            },
          },
          { upsert: true, new: true },
        );
      }));
    }));
  }

  async getDefaultOrganization() {
    return Organization.findOne({ isDefault: true }).lean<IOrganizationLean>().exec();
  }

  async getOrganizationForBorrower(borrowerId: string) {
    const borrower = await BorrowerModel.findById(borrowerId).lean<IBorrowerLean>().exec();
    const defaultOrganization = await this.getDefaultOrganization();
    if (!borrower) {
      return defaultOrganization;
    }
    const organization = await Organization.findById(borrower.organizationId).lean<IOrganizationLean>().exec();
    if (!organization) {
      return defaultOrganization;
    }
    return organization;
  }
}
