const mongoose = require("mongoose");
const validator = require("validator");
const bcrypt = require("bcryptjs");
const crypto = require("crypto");

const userSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, "A user must have a name"],
      trim: true,
    },
    email: {
      type: String,
      required: [true, "A user must have an email"],
      unique: true,
      lowercase: true,
      trim: true,
      validate: [validator.isEmail, "Please provide a valid email"],
    },
    googleId: {
      type: String,
      select: false,
    },
    gender: {
      type: String,
      enum: ["male", "female", "other"],
      default: "male",
    },
    photo: {
      type: String,
      trim: true,
    },
    role: {
      type: String,
      enum: ["student", "admin", "super-admin"],
      default: "student",
    },
    birthDate: {
      type: Date,
      required: [true, "Please provide your date of birth"],
    },
    password: {
      type: String,
      minlength: 8,
      select: false,
      required: [
        function () {
          return !this.googleId;
        },
        "A user must have a password",
      ],
    },
    passwordConfirm: {
      type: String,
      required: [
        function () {
          return this.password;
        },
        "Please confirm your password",
      ],
      validate: {
        validator: function (el) {
          return el === this.password;
        },
        message: "Passwords are not the same!",
      },
    },
    passwordChangedAt: Date,
    passwordResetToken: String,
    passwordResetExpires: Date,
    verificationCode: String,
    verificationCodeExpires: Date,

    isVerified: {
      type: Boolean,
      default: false,
    },
    active: {
      type: Boolean,
      default: true,
      select: false,
    },
    // 🔥 1. Timestamp required for Auto-Delete
    createdAt: {
      type: Date,
      default: Date.now,
    },
  },
  {
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
  }
);

userSchema.virtual("age").get(function () {
  if (!this.birthDate) return undefined;
  const today = new Date();
  const birthDate = new Date(this.birthDate);
  let age = today.getFullYear() - birthDate.getFullYear();
  const m = today.getMonth() - birthDate.getMonth();
  if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
    age--;
  }
  return age;
});

// ... Pre-save hooks remain the same ...
userSchema.pre("save", function (next) {
  if (!this.photo || this.photo.trim() === "") {
    this.photo =
      this.gender === "female" ? "defaultFemale.png" : "defaultMale.png";
  }
  if (this.isModified("password") && !this.isNew) {
    this.passwordChangedAt = Date.now() - 1000;
  }
  next();
});

userSchema.pre("save", async function (next) {
  if (!this.isModified("password")) return next();
  this.password = await bcrypt.hash(this.password, 12);
  this.passwordConfirm = undefined;
  next();
});

userSchema.pre(/^find/, function (next) {
  this.find({ active: { $ne: false } });
  next();
});

// ... Methods remain the same ...
userSchema.methods.correctPassword = async function (
  candidatePassword,
  userPassword
) {
  if (!userPassword) return false;
  return await bcrypt.compare(candidatePassword, userPassword);
};

userSchema.methods.changedPasswordAfter = function (JWTTimestamp) {
  if (this.passwordChangedAt) {
    const changedTimestamp = parseInt(
      this.passwordChangedAt.getTime() / 1000,
      10
    );
    return JWTTimestamp < changedTimestamp;
  }
  return false;
};

userSchema.methods.createPasswordResetToken = function () {
  const resetToken = crypto.randomBytes(32).toString("hex");
  this.passwordResetToken = crypto
    .createHash("sha256")
    .update(resetToken)
    .digest("hex");
  this.passwordResetExpires = Date.now() + 10 * 60 * 1000;
  return resetToken;
};

// 🔥 2. TTL Index: Auto-Delete Unverified Users after 10 Minutes (600s)
userSchema.index(
  { createdAt: 1 },
  {
    expireAfterSeconds: 600,
    partialFilterExpression: { isVerified: false }, // Only delete if NOT verified
  }
);

const User = mongoose.model("User", userSchema);
module.exports = User;
