/**
 * Demo / sample data for fresh MongoDB installs (buyers & local testing).
 * Run after MONGO_URI is set in backend/.env
 *
 *   cd backend && npm run seed
 *
 * Password for all demo users (change in production):
 *   EduConnectDemo2025!
 *
 * Keep DEMO_EMAILS and DEFAULT_DEMO_PASSWORD in sync with:
 *   frontend/src/config/demoLogin.js
 */

require("dotenv").config({ path: require("path").join(__dirname, "..", ".env") });
const mongoose = require("mongoose");

const User = require("../models/User");
const Subscription = require("../models/Subscription");
const Class = require("../models/Class");
const Notice = require("../models/Notice");
const SupportCategory = require("../models/SupportCategory");
const SupportSubcategory = require("../models/SupportSubcategory");
const FAQ = require("../models/FAQ");

const DEFAULT_DEMO_PASSWORD = "EduConnectDemo2025!";

const DEMO = {
  admin: { email: "admin@educonnect.demo", name: "Demo Admin" },
  teacher: { email: "teacher@educonnect.demo", name: "Demo Teacher" },
  institute: { email: "institute@educonnect.demo", name: "Demo Institute" },
  student: { email: "student@educonnect.demo", name: "Demo Student", username: "demo_student" },
};

async function connect() {
  if (!process.env.MONGO_URI) {
    console.error("Missing MONGO_URI. Copy .env.example to .env and set your MongoDB connection string.");
    process.exit(1);
  }
  await mongoose.connect(process.env.MONGO_URI);
  console.log("Connected to MongoDB");
}

async function ensureSubscription(plan, data) {
  let doc = await Subscription.findOne({ plan });
  if (doc) return doc;
  doc = await Subscription.create({ plan, ...data });
  console.log("Created subscription plan:", plan);
  return doc;
}

async function ensureUser(payload) {
  const existing = await User.findOne({ email: payload.email });
  if (existing) {
    console.log("Skip user (exists):", payload.email);
    return existing;
  }
  const user = await User.create(payload);
  console.log("Created user:", payload.email, `(${payload.role})`);
  return user;
}

async function run() {
  const reset = process.argv.includes("--reset");

  await connect();

  if (reset) {
    const emails = Object.values(DEMO).map((u) => u.email);
    const users = await User.find({ email: { $in: emails } });
    const ids = users.map((u) => u._id);
    if (ids.length) {
      await Notice.deleteMany({ teacherId: { $in: ids } });
      await Class.deleteMany({ teacherId: { $in: ids } });
    }
    await User.deleteMany({ email: { $in: emails } });
    console.log("Removed previous demo users (and their classes/notices).");
  }

  const subTeacher = await ensureSubscription("EduConnect Demo — Teacher", {
    studentLimit: 500,
    teacherAccounts: 5,
    storage: "10 GB",
    support: "Email",
    price: 0,
    status: "Active",
  });

  const subInstitute = await ensureSubscription("EduConnect Demo — Institute", {
    studentLimit: 2000,
    teacherAccounts: 50,
    storage: "100 GB",
    support: "Priority",
    price: 0,
    status: "Active",
  });

  await ensureUser({
    name: DEMO.admin.name,
    email: DEMO.admin.email,
    password: DEFAULT_DEMO_PASSWORD,
    role: "admin",
  });

  const teacher = await ensureUser({
    name: DEMO.teacher.name,
    email: DEMO.teacher.email,
    password: DEFAULT_DEMO_PASSWORD,
    role: "teacher",
    age: "30",
    contactNumber: "+10000000001",
    addressLine1: "1 Demo Street",
    addressLine2: "",
    district: "Demo District",
    zipCode: "00000",
    subscriptionId: subTeacher._id,
    subscriptionStatus: "active",
  });

  const institute = await ensureUser({
    name: DEMO.institute.name,
    email: DEMO.institute.email,
    password: DEFAULT_DEMO_PASSWORD,
    role: "institute",
    contactNumber: "+10000000002",
    addressLine1: "2 Institute Ave",
    addressLine2: "",
    district: "Demo District",
    zipCode: "00001",
    subscriptionId: subInstitute._id,
    subscriptionStatus: "active",
  });

  const student = await ensureUser({
    name: DEMO.student.name,
    email: DEMO.student.email,
    password: DEFAULT_DEMO_PASSWORD,
    role: "student",
    firstName: "Demo",
    lastName: "Student",
    username: DEMO.student.username,
    contactNumber: "+10000000003",
    dateOfBirth: "2005-01-01",
    guardianName: "Demo Guardian",
    guardianContactNumber: "+10000000004",
    addressLine1: "3 Student Rd",
    district: "Demo District",
    zipCode: "00002",
  });

  let demoClass = await Class.findOne({ subject: "Mathematics 101 (Demo)" });
  if (!demoClass) {
    demoClass = await Class.create({
      subject: "Mathematics 101 (Demo)",
      monthlyFee: 49.99,
      description: "Sample class created by the demo seed. Replace with your real classes.",
      teacherId: teacher._id,
      isActive: true,
    });
    console.log("Created demo class:", demoClass.subject);
  } else {
    console.log("Demo class already exists:", demoClass.subject);
  }

  const noticeCount = await Notice.countDocuments({ title: "Welcome to EduConnect (Demo)" });
  if (!noticeCount) {
    await Notice.create({
      title: "Welcome to EduConnect (Demo)",
      description:
        "This is a sample notice. Teachers can post announcements per class after you configure the app.",
      date: new Date(),
      classId: demoClass._id,
      teacherId: teacher._id,
    });
    console.log("Created demo notice.");
  } else {
    console.log("Demo notice already exists.");
  }

  let cat = await SupportCategory.findOne({ name: "General (Demo)" });
  if (!cat) {
    cat = await SupportCategory.create({ name: "General (Demo)" });
    await SupportSubcategory.create([
      { name: "Billing & payments", categoryId: cat._id },
      { name: "Technical issue", categoryId: cat._id },
    ]);
    console.log("Created demo support categories.");
  } else {
    console.log("Demo support category already exists.");
  }

  const faqExists = await FAQ.findOne({ question: "What is EduConnect?" });
  if (!faqExists) {
    await FAQ.insertMany([
      {
        question: "What is EduConnect?",
        answer:
          "EduConnect is a MERN-based learning platform for classes, materials, quizzes, and communication. Replace this FAQ with your own content in the admin panel.",
      },
      {
        question: "How do I change demo passwords?",
        answer:
          "Log in as admin, use profile or user management features if available, or update users directly in MongoDB after hashing a new password with bcrypt.",
      },
    ]);
    console.log("Inserted sample FAQs.");
  } else {
    console.log("Sample FAQs already exist.");
  }

  console.log("\n--- Demo seed complete ---");
  console.log("Admin:", DEMO.admin.email);
  console.log("Teacher:", DEMO.teacher.email);
  console.log("Institute:", DEMO.institute.email);
  console.log("Student:", DEMO.student.email);
  console.log("Password (all):", DEFAULT_DEMO_PASSWORD);
  console.log("\nSet VITE_SHOW_DEMO_ACCOUNTS=true in frontend/.env to show accounts on the login page.\n");

  await mongoose.disconnect();
}

run().catch((err) => {
  console.error(err);
  process.exit(1);
});
