import mongoose from 'mongoose';

import { MODEL_NAMES } from './_models';
import { ELoanTypes } from '../enums/loan-types.enum';
import { IBorrowerLean } from './Borrower.model';

export interface ILoanProduct {
  borrowerId: mongoose.Types.ObjectId;
  facilityId?: mongoose.Types.ObjectId | null;
  order: number;
  active: boolean;
  code: string;
  masterCode?: string;
  name: string;
  type: ELoanTypes;
  startDate: Date;
  maturityDate: Date;
  payoffDate?: Date;
  commitment: number;
  isBalanceActual: boolean;
  isFloatedBalanceActual: boolean;
  isParticipant?: boolean;
  masterLoanProductId?: mongoose.Types.ObjectId | null;
  minPercent: number;
  maxPercent: number;
  prepaymentDate?: Date;
  prepaymentTerms?: string;
  settlementCode: string;
  isDefaultPaymentOrder: boolean;
  calculationRequired: boolean;
  deactivationDate?: Date | null;
}

export interface ILoanProductDoc extends ILoanProduct, mongoose.Document {
  _id: mongoose.Types.ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

export interface ILoanProductLean extends ILoanProduct {
  _id: mongoose.Types.ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

export interface ILoanProductPlain extends Omit<ILoanProduct, 'borrowerId' | 'masterLoanProductId' | 'facilityId'> {
  _id: string;
  borrowerId: string;
  masterLoanProductId?: string | null;
  facilityId?: string | null;
}

export interface ILoanProductWithId extends ILoanProduct {
  _id: mongoose.Types.ObjectId;
}

export type ILoanProductView = Omit<ILoanProductWithId, 'borrowerId' | 'order'>;

export interface ILoanProductViewWithBalances extends ILoanProductView {
  balance: number;
  floatedBalance: number;
}

export interface ILoanProductLeanWithBorrower extends Omit<ILoanProductLean, 'borrowerId'> {
  borrowerId: IBorrowerLean;
}

export type TLoanProductModel = mongoose.Model<ILoanProduct>;

export const LoanProductSchema = new mongoose.Schema(
  {
    borrowerId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.borrowers,
      required: true,
    },
    facilityId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.facilities,
    },
    order: {
      type: Number,
      required: true,
    },
    active: {
      type: Boolean,
      required: true,
    },
    code: {
      type: String,
      trim: true,
      required: true,
    },
    masterCode: {
      type: String,
      trim: false,
    },
    name: {
      type: String,
      trim: true,
      required: true,
    },
    type: {
      type: String,
      required: true,
      trim: true,
    },
    startDate: {
      type: Date,
      required: true,
    },
    maturityDate: {
      type: Date,
      required: true,
    },
    payoffDate: {
      type: Date,
    },
    commitment: {
      type: Number,
      required: true,
    },
    isBalanceActual: {
      type: Boolean,
      required: true,
      default: true,
    },
    isFloatedBalanceActual: {
      type: Boolean,
      required: true,
      default: true,
    },
    isParticipant: {
      type: Boolean,
      required: false,
    },
    masterLoanProductId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.loanProducts,
      default: null,
    },
    minPercent: {
      type: Number,
      required: false,
    },
    maxPercent: {
      type: Number,
      required: false,
    },
    prepaymentDate: {
      type: Date,
    },
    prepaymentTerms: {
      type: String,
      trim: true,
    },
    settlementCode: {
      type: String,
      trim: true,
    },
    isDefaultPaymentOrder: {
      type: Boolean,
      required: true,
    },
    deactivationDate: {
      type: Date,
    },
    __v: { type: Number, select: false },
  },
  { timestamps: true },
);

export const LoanProduct = mongoose.model<ILoanProductDoc>(MODEL_NAMES.loanProducts, LoanProductSchema);
