import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument, Types } from 'mongoose';
import { User } from '../../users/schemas/user.schema';

export type NotificationDocument = HydratedDocument<Notification>;

export const NOTIFICATION_TYPES = [
  'like',
  'comment',
  'follow',
  'message',
  'save',
  'share',
  'mention',
  'reply',
  'system',
  'collaboration_request',
  'collaboration_request_approved',
  'collaboration_request_rejected',
  'collaboration_request_cancelled',
  'follow_request',
  'follow_request_approved',
  'follow_request_rejected',
  'support_reply',
  'support_ticket_status',
] as const;
export type NotificationType = (typeof NOTIFICATION_TYPES)[number];

@Schema({ timestamps: true, versionKey: false })
export class Notification {
  @Prop({ type: String, trim: true })
  eventId?: string;

  @Prop({ type: Types.ObjectId, ref: User.name, required: true, index: true })
  recipientId!: Types.ObjectId;

  @Prop({ type: Types.ObjectId, ref: User.name, required: true, index: true })
  actorId!: Types.ObjectId;

  @Prop({ type: String, required: true, enum: NOTIFICATION_TYPES })
  type!: NotificationType;

  @Prop({ type: Types.ObjectId })
  referenceId?: Types.ObjectId;

  @Prop({ default: '', trim: true, maxlength: 120 })
  title!: string;

  @Prop({ default: '', trim: true, maxlength: 500 })
  previewText!: string;

  @Prop({ default: '', trim: true, maxlength: 80, index: true })
  resourceType!: string;

  @Prop({ default: '', trim: true, maxlength: 240 })
  deepLink!: string;

  @Prop({ type: Object, default: {} })
  metadata!: Record<string, unknown>;

  @Prop({ default: false })
  read!: boolean;

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

export const NotificationSchema = SchemaFactory.createForClass(Notification);
NotificationSchema.index({ recipientId: 1, createdAt: -1 });
NotificationSchema.index({ recipientId: 1, read: 1, createdAt: -1 });
NotificationSchema.index({ recipientId: 1, read: 1, type: 1, createdAt: -1 });
NotificationSchema.index({ recipientId: 1, type: 1, createdAt: -1 });
NotificationSchema.index({ recipientId: 1, resourceType: 1, createdAt: -1 });
NotificationSchema.index({ referenceId: 1 });
NotificationSchema.index(
  { eventId: 1 },
  { unique: true, partialFilterExpression: { eventId: { $type: 'string' } } },
);
NotificationSchema.index(
  { recipientId: 1, type: 1, referenceId: 1 },
  {
    unique: true,
    partialFilterExpression: {
      type: 'follow_request_approved',
      referenceId: { $exists: true },
    },
  },
);
