import { Model, model, Schema } from "mongoose";
import { INotification } from "../interfaces/models/notificationInterface";

const NotificationSchema = new Schema<INotification>(
  {
    userId: {
      type: Schema.Types.ObjectId,
      ref: "User",
      required: true,
      index: true,
    },
    type: {
      type: String,
      required: true,
      enum: ["connection", "fuel", "chat", "trip_share", "payment"],
    },
    eventType: {
      type: String,
      required: true,
      enum: [
        "request_received",
        "accepted",
        "transferred",
        "message",
        "shared",
        "received",
      ],
    },
    title: { type: String, required: true, trim: true, maxlength: 200 },
    body: { type: String, required: true, trim: true, maxlength: 500 },
    data: {
      type: Map,
      of: String,
      default: {},
    },
    isRead: { type: Boolean, default: false, index: true },
    readAt: { type: Date, default: null },
    // Omit when unused — sparse unique index treats explicit null as a real key
    dedupeKey: { type: String, required: false },
  },
  { timestamps: true },
);

NotificationSchema.index({ userId: 1, createdAt: -1 });
NotificationSchema.index(
  { dedupeKey: 1 },
  { unique: true, sparse: true },
);

/**
 * Clear explicit null dedupeKeys so the sparse unique index works.
 * Mongo indexes `null` but skips missing fields — same class of bug as wallet txs.
 */
export async function ensureNotificationIndexes(): Promise<void> {
  const collection = NotificationModel.collection;

  try {
    const result = await collection.updateMany(
      { $or: [{ dedupeKey: null }, { dedupeKey: "" }] },
      { $unset: { dedupeKey: "" } },
    );
    if (result.modifiedCount > 0) {
      console.warn(
        `[notification-indexes] Unset null/empty dedupeKey on ${result.modifiedCount} document(s)`,
      );
    }
  } catch (e) {
    console.warn(
      "[notification-indexes] Could not unset null dedupeKeys:",
      e instanceof Error ? e.message : e,
    );
  }

  try {
    await NotificationModel.syncIndexes();
  } catch (e) {
    console.warn(
      "[notification-indexes] syncIndexes failed:",
      e instanceof Error ? e.message : e,
    );
  }
}

const NotificationModel: Model<INotification> = model<INotification>(
  "Notification",
  NotificationSchema,
);

export default NotificationModel;
