import { Schema } from "mongoose";
import { applyIdTransform, registerModel, stringId } from "../schema";
import {
  LEDGER_DIRECTIONS,
  LEDGER_ENTRY_TYPES,
  LEDGER_PARTY_ROLES,
  LEDGER_STATUSES,
} from "../types";

const LedgerEntrySchema = new Schema(
  {
    _id: stringId,
    type: { type: String, enum: LEDGER_ENTRY_TYPES, required: true, index: true },
    direction: { type: String, enum: LEDGER_DIRECTIONS, required: true },
    bookingId: { type: String, ref: "Booking", default: undefined, index: true },
    refundId: { type: String, ref: "Refund", default: undefined },
    withdrawalId: { type: String, ref: "WithdrawalRequest", default: undefined },
    amountLyd: { type: Number, required: true },
    amountTnd: { type: Number, required: true },
    partyUserId: { type: String, ref: "User", default: undefined, index: true },
    partyRole: { type: String, enum: LEDGER_PARTY_ROLES, required: true },
    status: { type: String, enum: LEDGER_STATUSES, default: "POSTED" },
    meta: { type: Schema.Types.Mixed, default: undefined },
  },
  { timestamps: true },
);

LedgerEntrySchema.index({ createdAt: -1 });
LedgerEntrySchema.index({ type: 1, createdAt: -1 });
// Idempotent booking payment posting
LedgerEntrySchema.index(
  { bookingId: 1, type: 1 },
  {
    unique: true,
    partialFilterExpression: { type: "BOOKING_PAYMENT", bookingId: { $type: "string" } },
  },
);
LedgerEntrySchema.index(
  { withdrawalId: 1, type: 1 },
  {
    unique: true,
    partialFilterExpression: { type: "WITHDRAWAL", withdrawalId: { $type: "string" } },
  },
);

applyIdTransform(LedgerEntrySchema);

export const LedgerEntry = registerModel("LedgerEntry", LedgerEntrySchema);
