import Joi from 'joi';
import mongoose, { Model } from 'mongoose';

import { MODEL_NAMES } from './_models';
import { ISelectedMonth } from '../helpers/date.helper';
import { BasicDTO } from '../helpers/db-data.helper';
import { EFinancialSpreadingType } from './FinancialSpreadingSheet.model';

export class FinancialSpreadingDTO extends BasicDTO {
  borrowerId: string;
  year: number;
  month: number;
  sheetId: string;
  amount: number;
}

export interface IFinancialSpreadingView {
  _id: string;
  borrowerId: string;
  year: number;
  month: number;
  sheetId: string;
  amount: number;
  minus_1?: number;
  minus_2?: number;
  minus_3?: number;
}

export interface IFinancialSpreadingUpload {
  _id: string;
  sheetId: string;
  sheetType: string;
  amount: number;
  title: string;
  isNew: boolean;
}

export interface IFinancialSpreadingViewWithDeepData extends IFinancialSpreadingView {
  [minus: string]: string | number | boolean;
}

export interface IFinancialSpreadingParams {
  borrowerId: string;
  selectedMonth: ISelectedMonth;
  financialSpreadingType: EFinancialSpreadingType;
}

export interface IFinancialSpreading {
  borrowerId: mongoose.Types.ObjectId;
  year: number;
  month: number;
  sheetId: mongoose.Types.ObjectId;
  amount: number;
}

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

export interface IFinancialSpreadingLean extends IFinancialSpreading {
  _id: mongoose.Types.ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

export interface IFinancialSpreadingPlain extends Omit<IFinancialSpreading, 'borrowerId' | 'sheetId'> {
  _id: string;
  borrowerId: string;
  sheetId: string;
  createdAt: Date;
  updatedAt: Date;
}

export const financialSpreadingViewValidationSchema = Joi.object<IFinancialSpreadingView>({
  _id: Joi.string().required(),
  borrowerId: Joi.string().required(),
  month: Joi.number().integer().min(1).max(12),
  year: Joi.number().integer().min(1900).max(9999),
  sheetId: Joi.string().required(),
  amount: Joi.number().required().allow(0),
  minus_1: Joi.number(),
  minus_2: Joi.number(),
  minus_3: Joi.number(),
});

export const financialSpreadingParamsValidationSchema = Joi.object<IFinancialSpreadingParams>({
  borrowerId: Joi.string().required(),
  selectedMonth: Joi.object({
    month: Joi.number().integer().min(1).max(12),
    year: Joi.number().integer().min(1900).max(9999),
  }).required(),
  financialSpreadingType: Joi.string().valid(...Object.values(EFinancialSpreadingType)),
});

export type IFinancialSpreadingModel = Model<IFinancialSpreading, object, object>;

export const FinancialSpreadingSchema = new mongoose.Schema<IFinancialSpreading, IFinancialSpreadingModel>(
  {
    borrowerId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.borrowers,
      required: true,
    },
    year: {
      type: Number,
      required: true,
    },
    month: {
      type: Number,
      required: true,
    },
    sheetId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.financialSpreadingSheets,
      required: true,
    },
    amount: {
      type: Number,
      required: true,
    },
  },
  {
    timestamps: { createdAt: true, updatedAt: true },
  },
);

export const FinancialSpreading = mongoose.model<IFinancialSpreading, IFinancialSpreadingModel>(MODEL_NAMES.financialSpreading, FinancialSpreadingSchema);
