import mongoose, { Model } from 'mongoose';

import { MODEL_NAMES } from './_models';
import {
  IBorrowerItemLean,
  IEmailRecipient,
} from './ComplianceItem.model';
import { IBorrowerDoc } from './Borrower.model';

export interface IComplianceNote {
  note: string;
  date: Date;
  user?: string;
}

export interface IComplianceBorrower {
  isVisible: boolean;
  borrower: mongoose.Types.ObjectId;
  complianceNotes?: IComplianceNote[];
  borrowerNotes?: IComplianceNote[];
  email?: string;
  mainEmails?: IEmailRecipient[];
  financialEmails?: IEmailRecipient[];
  isEmailingActive?: boolean;
  isDailyTransactionsEmailingActive?: boolean;
  plaidAccessToken?: string;
  fundingStatus?: string;
  lastEmailSentAt?: Date;
  items?: IBorrowerItemLean[];
}

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

export interface IComplianceBorrowerLean extends IComplianceBorrower {
  _id: mongoose.Types.ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

export interface IComplianceBorrowerWithPlaidToken extends IComplianceBorrowerLean {
  plaidAccessToken: string;
}

export interface IComplianceBorrowerPlain extends Omit<IComplianceBorrower, 'borrower'> {
  _id: string;
  borrower: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface IComplianceBorrowerWithBorrower extends Omit<IComplianceBorrowerLean, 'borrower'> {
  borrower: IBorrowerDoc;
  createdAt: Date;
  updatedAt: Date;
}

export type ComplianceBorrowerModel = Model<IComplianceBorrowerDoc>;

export interface IComplianceBorrowerDocumentFull extends Omit<IComplianceBorrowerWithBorrower, 'items'> {
  items: IBorrowerItemLean[];
}

const BorrowerComplianceInstanceSchema = new mongoose.Schema({
  nextDate: {
    type: Date,
    required: false,
  },
  submittedDate: {
    type: Date,
    required: false,
  },
  status: {
    type: String,
    trim: true,
    required: false,
  },
  files: [{
    fileId: {
      type: String,
      trim: true,
      required: true,
    },
    name: {
      type: String,
      trim: true,
      required: true,
    },
    isFileNew: {
      type: Boolean,
      required: false,
      default: true,
    },
    uploadedAt: {
      type: Date,
      required: false,
    },
    uploadedBy: {
      type: String,
      required: false,
    },
  }],
}, { timestamps: true });

const BorrowerComplianceItemSchema = new mongoose.Schema({
  item: {
    type: mongoose.Schema.Types.ObjectId,
    ref: MODEL_NAMES.complianceItems,
    required: false,
  },
  startDate: {
    type: Date,
    required: false,
  },
  frequency: {
    type: String,
    trim: true,
    required: false,
  },
  emailAddresses: [{
    email: {
      type: String,
      trim: true,
      required: false,
    },
    title: {
      type: String,
      trim: true,
      required: false,
    },
    isActive: {
      type: Boolean,
      required: false,
    },
  }],
  instances: [BorrowerComplianceInstanceSchema],
}, { timestamps: true });

export const BorrowerComplianceSchema = new mongoose.Schema(
  {
    isVisible: {
      type: Boolean,
    },
    borrower: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.borrowers,
      required: true,
    },
    complianceNotes: [{
      note: {
        type: String,
        trim: true,
        required: true,
      },
      date: {
        type: Date,
        required: true,
      },
      user: {
        type: String,
        trim: true,
        required: false,
      },
    }],
    borrowerNotes: [{
      note: {
        type: String,
        trim: true,
        required: true,
      },
      date: {
        type: Date,
        required: true,
      },
      user: {
        type: String,
        trim: true,
        required: false,
      },
    }],
    email: {
      type: String,
      trim: true,
      required: false,
    },
    mainEmails: [{
      email: {
        type: String,
        trim: true,
        required: false,
      },
      title: {
        type: String,
        trim: true,
        required: false,
      },
      isActive: {
        type: Boolean,
        required: false,
      },
    }],
    financialEmails: [{
      email: {
        type: String,
        trim: true,
        required: false,
      },
      title: {
        type: String,
        trim: true,
        required: false,
      },
      isActive: {
        type: Boolean,
        required: false,
      },
    }],
    isEmailingActive: {
      type: Boolean,
      required: false,
      default: false,
    },
    isDailyTransactionsEmailingActive: {
      type: Boolean,
      required: false,
      default: false,
    },
    plaidAccessToken: {
      type: String,
      trim: true,
      required: false,
      select: false,
    },
    fundingStatus: {
      type: String,
      trim: true,
      required: false,
    },
    lastEmailSentAt: {
      type: Date,
      required: false,
    },
    items: [BorrowerComplianceItemSchema],
    __v: { type: Number, select: false },
  },
  { timestamps: true },
);

export const BorrowerCompliance = mongoose.model<IComplianceBorrowerDoc>(MODEL_NAMES.complianceBorrowers, BorrowerComplianceSchema);
