import mongoose, { Model } from 'mongoose';

import { MODEL_NAMES } from './_models';

export interface ISplitTransaction {
  _id?: mongoose.Types.ObjectId;
  reference: string;
  referenceId: mongoose.Types.ObjectId;
  memo: string;
  amount: number;
}

export interface IUploadedBankTransaction {
  _id?: mongoose.Types.ObjectId;
  order: number;
  date: Date;
  accountNumber?: string;
  amount: number;
  transactionType?: string;
  reference: string;
  detail1?: string;
  detail2?: string;
  detail3?: string;
  credit?: number;
  debit?: number;
  isConverted: boolean;
  loanTransactionIds?: mongoose.Types.ObjectId[];
  splitTransactions: ISplitTransaction[];
  bankIntegrationTransactionId?: mongoose.Types.ObjectId;
}

export type IUploadedBankTransactionDoc = mongoose.HydratedDocument<IUploadedBankTransaction>;

export interface IUploadedBankTransactionWithMemo extends IUploadedBankTransaction {
  splitMemo: string;
}

export interface IUploadedBankTransactionWithInfo extends IUploadedBankTransaction {
  hasMatch: boolean;
  canSplit: boolean;
}

export interface IUploadedBankTransactionLean extends IUploadedBankTransaction {
  _id: mongoose.Types.ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

export interface IUploadedBankTransactionPlain extends Omit<IUploadedBankTransaction, '_id' | 'loanTransactionIds' | 'bankIntegrationTransactionId'> {
  _id: string;
  loanTransactionIds: string[];
  bankIntegrationTransactionId: string;
}

type UploadedBankTransactionModel = mongoose.Model<IUploadedBankTransaction>;
type SplitTransactionModel = mongoose.Model<ISplitTransaction>;

const SplitTransactionSchema = new mongoose.Schema<ISplitTransaction, SplitTransactionModel>({
  reference: {
    type: String,
    required: true,
  },
  referenceId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: MODEL_NAMES.cashAllocationReferences,
    required: true,
  },
  memo: {
    type: String,
    required: false,
  },
  amount: {
    type: Number,
    required: true,
  },
});

export const UploadedBankTransactionSchema = new mongoose.Schema<IUploadedBankTransaction, UploadedBankTransactionModel>({
  date: {
    type: Date,
    required: true,
  },
  accountNumber: {
    type: String,
    required: false,
    trim: true,
  },
  amount: {
    type: Number,
    required: true,
  },
  transactionType: {
    type: String,
    required: false,
    trim: true,
  },
  reference: {
    type: String,
    required: true,
    trim: true,
  },
  detail1: {
    type: String,
    required: false,
    trim: true,
  },
  detail2: {
    type: String,
    required: false,
    trim: true,
  },
  detail3: {
    type: String,
    required: false,
    trim: true,
  },
  isConverted: {
    type: Boolean,
    required: false,
  },
  loanTransactionIds: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: MODEL_NAMES.loanTransactions,
    required: false,
  }],
  splitTransactions: [SplitTransactionSchema],
  bankIntegrationTransactionId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: MODEL_NAMES.bankIntegrationTransactions,
    required: false,
  },
}, { timestamps: { createdAt: true, updatedAt: false } });

export const UploadedBankTransaction = mongoose.model<IUploadedBankTransaction, UploadedBankTransactionModel>(MODEL_NAMES.uploadedBankTransactions, UploadedBankTransactionSchema);
