import mongoose, { Document, Schema } from "mongoose";

export interface IUserDeviceToken {
  token: string;
  platform: "android" | "ios" | "web";
  updatedAt: Date;
}

export interface IUserDocument extends Document {
  id: string;
  name: string;
  email: string;
  password?: string;
  role: string;
  avatar: string | null;
  phone: string | null;
  address: string | null;
  department: string | null;
  designation: string | null;
  employee_id: string | null;
  joining_date: Date | null;

  quiz_points: number;
  sudoku_points: number;
  zipline_points: number;
  spin_wheel_points: number;
  earned_points: number;
  redeemed_points: number;

  total_points: number; // virtual (still exposed)

  currentStreak: number;
  longestStreak: number;
  lastCheckInDate: string | null;

  status: "active" | "inactive";
  tokenVersion: number;
  refreshToken?: string | null;
  resetToken?: string | null;
  resetTokenExpiry?: Date | null;

  deviceTokens: IUserDeviceToken[];

  createdAt: Date;
  updatedAt: Date;
}

const userSchema = new Schema<IUserDocument>(
  {
    name: { type: String, required: true, trim: true },
    email: { type: String, required: true, unique: true, trim: true },
    password: { type: String, select: false },
    role: { type: String, default: "user" },

    avatar: { type: String, default: null },
    phone: { type: String, default: null },
    address: { type: String, default: null },
    department: { type: String, default: null },
    designation: { type: String, default: null },

    employee_id: { type: String, unique: true, sparse: true },
    joining_date: { type: Date, default: null },

    quiz_points: { type: Number, default: 0 },
    sudoku_points: { type: Number, default: 0 },
    zipline_points: { type: Number, default: 0 },
    spin_wheel_points: { type: Number, default: 0 },
    earned_points: { type: Number, default: 0 },
    redeemed_points: { type: Number, default: 0 },

    currentStreak: { type: Number, default: 0 },
    longestStreak: { type: Number, default: 0 },
    lastCheckInDate: { type: String, default: null },

    status: { type: String, enum: ["active", "inactive"], default: "active" },

    tokenVersion: { type: Number, default: 0 },
    refreshToken: { type: String, default: null, select: false },
    resetToken: { type: String, default: null, select: false },
    resetTokenExpiry: { type: Date, default: null, select: false },

    deviceTokens: [
      {
        token: { type: String, required: true },
        platform: {
          type: String,
          enum: ["android", "ios", "web"],
          default: "android",
        },
        updatedAt: { type: Date, default: Date.now },
      },
    ],
  },
  { timestamps: true },
);

//
// ✅ Virtual must be OUTSIDE schema definition
//
userSchema.virtual("total_points").get(function (this: IUserDocument) {
  return (this.earned_points || 0) - (this.redeemed_points || 0);
});

//
// ✅ Include virtuals in responses
//
userSchema.set("toJSON", { virtuals: true });
userSchema.set("toObject", { virtuals: true });

export default mongoose.model<IUserDocument>("User", userSchema);
