import mongoose, { Model } from 'mongoose';

import { MODEL_NAMES } from './_models';
import { RISK_RATINGS } from './ScorecardVersion.model';

export const RESULT_SOURCES = [
  'SCORE',
  'RULE',
] as const;

export type TResultSource = typeof RESULT_SOURCES[number];

export const SUBMISSION_STATUSES = [
  'draft',
  'final',
] as const;

export type TSubmissionStatus = typeof SUBMISSION_STATUSES[number];

export interface IStorecardSubmission {
  borrowerId: mongoose.Types.ObjectId;
  scorecardId: mongoose.Types.ObjectId;
  scorecardVersionId: mongoose.Types.ObjectId;
  period: string;
  totalScore?: number;
  sectionScores?: Record<string, number>;
  status: TSubmissionStatus;
  lockedAt: Date;
  finalResult?: string;
  resultSource?: TResultSource;
  resultRuleKey?: string;
}

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

export interface IStorecardSubmissionLean extends IStorecardSubmission {
  _id: mongoose.Types.ObjectId;
  createdAt: Date;
  updatedAt: Date;
}

export interface IScorecardSubmissionPlain extends Omit<IStorecardSubmission, 'borrowerId' | 'scorecardId' | 'scorecardVersionId'> {
  _id: string;
  borrowerId: string;
  scorecardId: string;
  scorecardVersionId: string;
}

export type TStorecardSubmissionModel = Model<IStorecardSubmission>;

export const StorecardSubmissionSchema = new mongoose.Schema<IStorecardSubmission, TStorecardSubmissionModel>(
  {
    borrowerId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.borrowers,
      required: true,
    },
    scorecardId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.scorecard,
      required: true,
    },
    scorecardVersionId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: MODEL_NAMES.scorecardVersion,
      required: true,
    },
    period: {
      type: String,
      required: true,
    },
    totalScore: {
      type: Number,
    },
    sectionScores: {
      type: Map,
      of: Number,
      required: false,
    },
    status: {
      type: String,
      enum: SUBMISSION_STATUSES,
      required: true,
    },
    lockedAt: {
      type: Date,
      required: false,
    },
    finalResult: {
      type: String,
      required: false,
    },
    resultSource: {
      type: String,
      enum: RESULT_SOURCES,
      required: false,
    },
    resultRuleKey: {
      type: String,
      required: false,
    },
  },
  {
    timestamps: { createdAt: true, updatedAt: true },
    versionKey: false,
  },
);

export const StorecardSubmission = mongoose.model<IStorecardSubmission, TStorecardSubmissionModel>(MODEL_NAMES.scorecardSubmission, StorecardSubmissionSchema);

StorecardSubmissionSchema.index(
  { borrowerId: 1, scorecardId: 1, period: 1 },
  { unique: true }
);
