import mongoose, { Model } from 'mongoose';

import { MODEL_NAMES } from './_models';
import { IBorrowerNoteSubjectLean, IBorrowerNoteSubjectPlain } from './BorrowerNoteSubject.model';

type BorrowerNoteStatus =
  | 'draft'
  | 'processing'
  | 'ready'
  | 'failed';

export interface IBorrowerNoteAttachment {
  fileId: string;
  fileName: string;
  filePath: string;
  mimeType: string;
  size: number;
  fieldName: string;
  contentId: string | null;
  isInline: boolean;
}

export interface IBorrowerNote {
  taskId?: string;
  status: BorrowerNoteStatus;
  borrowerId: mongoose.Types.ObjectId;
  subjectId?: mongoose.Types.ObjectId;
  text?: string;
  attachments: IBorrowerNoteAttachment[];
  createdBy: string;
  updatedBy?: string;
  source?: {
    type: 'manual' | 'email';
    emailFrom?: string;
    emailTo?: string;
    emailText?: string;
    emailHtml?: string;
  };
}

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

export interface IBorrowerNoteCreate extends Omit<IBorrowerNote, '_id' | 'borrowerId' | 'attachments' | 'updatedBy'> {
  borrowerId: string;
}

export interface IBorrowerNoteUpdate extends Omit<IBorrowerNote, '_id' | 'borrowerId' | 'attachments' | 'createdBy'> {
  borrowerId: string;
  removedAttachments: string[];
}

export interface IBorrowerNoteLean extends IBorrowerNote {
  _id: mongoose.Types.ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

export interface IBorrowerNoteWithSubjectLean extends Omit<IBorrowerNoteLean, 'subjectId'> {
  subjectId: IBorrowerNoteSubjectLean | null;
}

export interface IBorrowerNotePlain extends Omit<IBorrowerNote, 'borrowerId' | 'subjectId'> {
  _id: string;
  borrowerId: string;
  subjectId: string;
  createdAt: string;
  updatedAt: string;
}

export interface IBorrowerNoteWithSubjectPlain extends Omit<IBorrowerNotePlain, 'subjectId'> {
  subjectId: IBorrowerNoteSubjectPlain | null;
}

export type BorrowerNoteModel = Model<IBorrowerNoteDoc>;

const BorrowerNoteAttachmentSchema = new mongoose.Schema<IBorrowerNoteAttachment>({
  fileId: {
    type: String,
    required: true,
  },
  fileName: {
    type: String,
    required: true,
  },
  filePath: {
    type: String,
    required: true,
  },
  mimeType: {
    type: String,
    required: false,
  },
  size: {
    type: Number,
    required: false,
  },
  fieldName: {
    type: String,
    required: false,
  },
  contentId: {
    type: String,
    required: false,
    default: null,
  },
  isInline: {
    type: Boolean,
    required: true,
    default: false,
  },
});

export const BorrowerNoteSchema = new mongoose.Schema<IBorrowerNoteDoc>({
  taskId: {
    type: String,
    required: true,
    index: true,
  },
  borrowerId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: MODEL_NAMES.borrowers,
    required: true,
    index: true,
  },
  status: {
    type: String,
    enum: ['draft', 'processing', 'ready', 'failed'],
    default: 'draft',
    index: true,
  },
  text: {
    type: String,
    required: false,
  },
  subjectId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: MODEL_NAMES.borrowerNoteSubject,
    required: false,
    index: true,
  },
  createdBy: {
    type: String,
    required: true,
  },
  updatedBy: {
    type: String,
  },
  attachments: [BorrowerNoteAttachmentSchema],
  source: {
    type: {
      type: String,
      enum: ['manual', 'email'],
      default: 'manual',
    },
    emailFrom: { type: String },
    emailTo: { type: String },
    emailText: { type: String },
    emailHtml: { type: String },
  },
}, {
  timestamps: true,
  versionKey: false,
});

export const BorrowerNote = mongoose.model<IBorrowerNoteDoc>(MODEL_NAMES.borrowerNote, BorrowerNoteSchema);
