import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type OutboxEventDocument = HydratedDocument<OutboxEvent>;

@Schema({ timestamps: true, versionKey: false })
export class OutboxEvent {
  declare createdAt: Date;

  declare updatedAt: Date;

  @Prop({ required: true })
  eventId!: string;

  @Prop({ required: true, index: true })
  eventType!: string;

  @Prop({ required: true, type: Object })
  payload!: Record<string, unknown>;

  @Prop({
    required: true,
    default: 'pending',
    enum: ['pending', 'processing', 'processed', 'failed', 'dead'],
    index: true,
  })
  status!: 'pending' | 'processing' | 'processed' | 'failed' | 'dead';

  @Prop({ required: true, default: 0, min: 0 })
  attempts!: number;

  @Prop({ default: '' })
  lastError!: string;

  @Prop({ type: Date, default: Date.now, index: true })
  nextRetryAt!: Date;

  @Prop({ type: Date, default: null, index: true })
  lockedAt?: Date | null;

  @Prop({ type: String, default: null })
  lockedBy?: string | null;

  @Prop({ default: '' })
  correlationId!: string;

  @Prop({ default: '' })
  requestId!: string;

  @Prop({ type: Date, default: null, index: true })
  processedAt?: Date | null;

  @Prop({ type: Date, default: null })
  deadAt?: Date | null;
}

export const OutboxEventSchema = SchemaFactory.createForClass(OutboxEvent);
OutboxEventSchema.index(
  { eventId: 1 },
  { unique: true, partialFilterExpression: { eventId: { $type: 'string' } } },
);
OutboxEventSchema.index({ eventType: 1, status: 1, nextRetryAt: 1, lockedAt: 1, createdAt: 1 });
