import mongoose, { Schema, Document, Model } from 'mongoose';

export interface IGuestInfo {
  name: string;
  mobile?: string;
  city?: string;
}

export interface ICorrectionRecord {
  previousStatus: 'Present' | 'Absent';
  newStatus: 'Present' | 'Absent';
  changedBy: mongoose.Types.ObjectId;
  changedAt: Date;
  reason?: string;
}

export interface IAttendance extends Document {
  satsangId: mongoose.Types.ObjectId;
  memberId?: mongoose.Types.ObjectId; // References Member, optional for Guest
  guestInfo?: IGuestInfo;
  status: 'Present' | 'Absent';
  markedBy: mongoose.Types.ObjectId; // References User
  markedAt: Date;
  notes: string;
  syncId?: string; // Client-side generated transaction UUID, optional for online mark
  isCorrection: boolean;
  correctionHistory: ICorrectionRecord[];
  createdAt: Date;
  updatedAt: Date;
}

const GuestInfoSchema = new Schema<IGuestInfo>({
  name: { type: String, required: true, trim: true },
  mobile: { type: String, trim: true, default: '' },
  city: { type: String, trim: true, default: '' }
}, { _id: false });

const CorrectionRecordSchema = new Schema<ICorrectionRecord>({
  previousStatus: { type: String, enum: ['Present', 'Absent'], required: true },
  newStatus: { type: String, enum: ['Present', 'Absent'], required: true },
  changedBy: { type: Schema.Types.ObjectId, ref: 'User', required: true },
  changedAt: { type: Date, default: Date.now },
  reason: { type: String, trim: true, default: '' }
}, { _id: false });

const AttendanceSchema = new Schema<IAttendance>({
  satsangId: { type: Schema.Types.ObjectId, ref: 'Satsang', required: true },
  memberId: { type: Schema.Types.ObjectId, ref: 'Member' },
  guestInfo: { type: GuestInfoSchema },
  status: {
    type: String,
    enum: ['Present', 'Absent'],
    required: true,
    default: 'Present'
  },
  markedBy: { type: Schema.Types.ObjectId, ref: 'User', required: true },
  markedAt: { type: Date, default: Date.now },
  notes: { type: String, default: '', trim: true },
  syncId: { type: String }, // Optional online, unique sparse index
  isCorrection: { type: Boolean, default: false },
  correctionHistory: { type: [CorrectionRecordSchema], default: [] }
}, {
  timestamps: true
});

// Unique partial index for memberId per satsangId (only when memberId is a valid ObjectId)
AttendanceSchema.index(
  { satsangId: 1, memberId: 1 },
  { unique: true, partialFilterExpression: { memberId: { $type: "objectId" } } }
);

// Unique sparse index on syncId for idempotency (handles missing values without duplicate key errors)
AttendanceSchema.index(
  { syncId: 1 },
  { unique: true, sparse: true }
);

// Performance indexes for directory queries, Last Attended lookups, and reporting lists
AttendanceSchema.index({ memberId: 1, status: 1, markedAt: -1 });
AttendanceSchema.index({ satsangId: 1, status: 1, markedAt: -1 });

export const Attendance: Model<IAttendance> =
  mongoose.models.Attendance || mongoose.model<IAttendance>('Attendance', AttendanceSchema);
export default Attendance;
