import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
import { BaseEntity } from '../../common/entities/base.entity';
import { Exclude } from 'class-transformer';
import { NotificationPrefs, NotificationPrefsSchema } from '../../common/schemas/notification-prefs.schema';

export type StudentDocument = Student & Document;

@Schema({ _id: false })
class ParentInfo {
  @Prop() name?: string;
  @Prop({ trim: true, lowercase: true }) email?: string;
  @Prop() occupation?: string;
  @Prop() monthlyIncome?: string;
  @Prop() phone?: string;
  @Prop() whatsapp?: string;
}
const ParentInfoSchema = SchemaFactory.createForClass(ParentInfo);

@Schema({ _id: false })
class Documents {
  @Prop() photoUrl?: string;
  @Prop() fatherPhotoUrl?: string;
  @Prop() motherPhotoUrl?: string;
  @Prop() birthCertificateUrl?: string;
  @Prop() scstCertificateUrl?: string;
  @Prop() leavingCertificateUrl?: string;
  @Prop() vaccineCardUrl?: string;
}
const DocumentsSchema = SchemaFactory.createForClass(Documents);

@Schema({ _id: false })
class CustomDocument {
  @Prop({ required: true })
  title: string;

  @Prop()
  publishedBy?: string;

  @Prop({ required: true })
  documentUrl: string;

  @Prop({ type: Date, default: Date.now })
  uploadDate: Date;
}
const CustomDocumentSchema = SchemaFactory.createForClass(CustomDocument);

@Schema({ _id: false })
class CustomImage {
  @Prop()
  title?: string;

  @Prop({ required: true })
  imageUrl: string;

  @Prop({ type: Date, default: Date.now })
  uploadDate: Date;
}
const CustomImageSchema = SchemaFactory.createForClass(CustomImage);

@Schema({ _id: false })
class EducationEntry {
  @Prop({ required: true })
  degree: string;

  @Prop({ required: true })
  institution: string;

  @Prop({ type: Date, required: true })
  startDate: Date;

  @Prop({ type: Date })
  endDate?: Date;

  @Prop()
  grade?: string;
}
const EducationEntrySchema = SchemaFactory.createForClass(EducationEntry);

@Schema({ timestamps: true })
export class Student extends BaseEntity {
  // Account
  @Prop({ required: true, trim: true })
  name: string;

  // Auto-generated unique student ID (e.g., STU-2025-0001)
  @Prop({ unique: true, sparse: true, trim: true })
  uniqueId?: string;

  // Roll is unique within (academicYearId, classId, sectionId) — see compound index below
  @Prop({ required: true, trim: true })
  rollNumber: string;

  @Prop({ unique: true, sparse: true, trim: true, lowercase: true })
  email?: string;

  @Exclude()
  @Prop()
  password?: string;

  @Prop({ default: 'student' })
  role: string;

  // Enrolment (current snapshot)
  @Prop() classId: string;
  @Prop() sectionId: string;
  @Prop() academicYearId: string;
  @Prop() gender: string;
  @Prop() dateOfBirth: Date;
  @Prop({ type: Date }) admissionDate?: Date;

  // Student info
  @Prop() motherTongue?: string;
  @Prop({ trim: true })
  religion?: string;

  @Prop({ trim: true })
  caste?: string;

  @Prop({ trim: true })
  mediumOfInstruction?: string;

  @Prop({ trim: true })
  nationality?: string;

  @Prop({ trim: true })
  previousSchoolName?: string;

  @Prop({ default: false })
  tcIssued?: boolean;

  @Prop({ default: true })
  clearedAllDues?: boolean;

  @Prop({ trim: true })
  tcNumber?: string;

  @Prop() bloodGroup?: string;
  @Prop() heightCm?: string;
  @Prop() weightKg?: string;

  // Medical Information
  @Prop({ trim: true })
  medicalConditions?: string;

  @Prop({ default: false })
  hasAllergies?: boolean;

  @Prop({ trim: true })
  allergyDetails?: string;

  @Prop({ trim: true })
  emergencyMedicalInstructions?: string;

  @Prop() guardianName?: string;
  @Prop() guardianRelation?: string;
  @Prop() phone?: string;
  @Prop() whatsapp?: string;
  @Prop() address?: string;

  // Transport
  @Prop({ default: false })
  transportRequired?: boolean;

  @Prop({ trim: true })
  routePickupPoint?: string;

  // Status
  @Prop({ default: true, index: true })
  isActive: boolean;

  // Exit Details
  @Prop({ type: Date })
  leavingDate?: Date;

  @Prop({ trim: true })
  leavingReason?: string;

  // Parents
  @Prop({ type: ParentInfoSchema }) father?: ParentInfo;
  @Prop({ type: ParentInfoSchema }) mother?: ParentInfo;

  // Uploads
  @Prop({ type: DocumentsSchema }) documents?: Documents;

  // Custom Documents and Images
  @Prop({ type: [CustomDocumentSchema], default: [] })
  customDocuments?: CustomDocument[];

  @Prop({ type: [CustomImageSchema], default: [] })
  customImages?: CustomImage[];

  // Education History
  @Prop({ type: [EducationEntrySchema], default: [] })
  education?: EducationEntry[];

  // Self-service profile image (separate from documents.photoUrl which is the formal photo)
  @Prop({ trim: true })
  profileImageUrl?: string;

  // === Notification Preferences ===
  @Prop({ type: NotificationPrefsSchema, default: () => ({ email: true, whatsapp: true }) })
  notificationPrefs?: NotificationPrefs;
}

export const StudentSchema = SchemaFactory.createForClass(Student);

// Helpful indexes
StudentSchema.index({ classId: 1 });
StudentSchema.index({ sectionId: 1 });
StudentSchema.index({ academicYearId: 1 });

// Roll number unique per (AY, class, section) for current snapshot.
// When sectionId is absent, null is a single bucket so uniqueness falls back to (AY, class).
StudentSchema.index(
  { academicYearId: 1, classId: 1, sectionId: 1, rollNumber: 1 },
  { unique: true, sparse: true },
);

// JSON shape
StudentSchema.set('toJSON', { versionKey: false });
StudentSchema.set('toObject', { versionKey: false });
