const mongoose = require("mongoose");
const slugify = require("slugify");
// Import related models so we can fetch details before saving
const Campus = require("./campusModel");
const Category = require("./categoryModel"); // Assuming you have this
const Instructor = require("./staffModel"); // Assuming you have this (or User)

const courseSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, "A course must have a name"],
      trim: true,
      unique: true,
    },
    slug: String,
    subtitle: { type: String, trim: true },
    coverImage: { type: String, required: true },
    images: [String],
    promoVideo: String,
    price: { type: Number, required: true },
    currency: {
      type: String,
      enum: ["USD", "EUR", "EGP", "GBP", "SAR", "AED"],
      default: "SAR",
    },
    description: { type: String, required: true },
    stacks: [String],
    status: {
      type: String,
      enum: ["available", "not available", "upcoming"],
      default: "available",
    },
    mode: {
      type: String,
      enum: [
        "On-Demand (Pre-Recorded)",
        "In-Person/ On-Site",
        "Hybrid",
        "Live Online",
      ],
      default: "hybrid",
    },
    certificateTemplate: {
      type: String,
      default: "default-cert.png", // Fallback image
    },
    // --- EMBEDDED RELATIONSHIPS (The Fix) ---
    // Instead of just ID, we store the snapshot of data we need for the card

    instructors: [
      {
        _id: { type: mongoose.Schema.ObjectId, ref: "Instructor" },
        name: String,
        photo: String,
      },
    ],

    category: {
      _id: { type: mongoose.Schema.ObjectId, ref: "Category" },
      name: String,
      icon: String,
    },

    campus: {
      _id: { type: mongoose.Schema.ObjectId, ref: "Campus" },
      name: String,
      floor: String,
    },

    ratingsAverage: {
      type: Number,
      default: 4.5,
      set: (val) => Math.round(val * 10) / 10,
    },
    ratingsQuantity: { type: Number, default: 0 },
  },
  {
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
  }
);

// 1. Slugify Middleware
courseSchema.pre("save", function (next) {
  if (this.name) {
    this.slug = slugify(this.name, { lower: true });
  }
  next();
});

// 2. 🚀 THE MAGIC FIX: Pre-Save Hook (Denormalization)
// This runs BEFORE saving to DB. It fetches the names/images and stores them inside the course.
// This means we NEVER need to populate when reading!
courseSchema.pre("save", async function (next) {
  // A. Embed Campus Details if modified
  if (this.isModified("campus") || this.isNew) {
    // If user sent just an ID string, we assume it's in the _id field or the root
    const campusId = this.campus._id || this.campus;
    const campusDoc = await Campus.findById(campusId);
    if (campusDoc) {
      this.campus = {
        _id: campusDoc._id,
        name: campusDoc.name,
        floor: campusDoc.floor,
      };
    }
  }

  // B. Embed Category Details if modified
  if (this.isModified("category") || this.isNew) {
    const catId = this.category._id || this.category;
    const catDoc = await Category.findById(catId);
    if (catDoc) {
      this.category = {
        _id: catDoc._id,
        name: catDoc.name,
        icon: catDoc.icon,
      };
    }
  }

  // C. Embed Instructors Details if modified
  if (this.isModified("instructors") || this.isNew) {
    // Assuming 'instructors' comes as an array of IDs from the frontend
    const instructorIds = this.instructors.map((i) => i._id || i);
    const staffDocs = await Instructor.find({ _id: { $in: instructorIds } });

    // Map the found docs to our embedded structure
    this.instructors = staffDocs.map((staff) => ({
      _id: staff._id,
      name: staff.name,
      photo: staff.photo,
    }));
  }

  next();
});

// ❌ REMOVED: The pre(/^find/) middleware.
// We no longer need it because the data is already inside the document!

const Course = mongoose.model("Course", courseSchema);
module.exports = Course;
