const prisma = require("../lib/prisma");

exports.getMyEnrollments = async (req, res) => {
  try {
    const studentId = req.user.id;

    // ===== Pagination =====
    const page = Number(req.query.page) || 0;
    const pageSize = Number(req.query.pageSize) || 10;

    // ===== Sorting =====
    let orderBy = [];
    if (req.query.sort) {
      try {
        const sortModel = JSON.parse(req.query.sort);
        orderBy = sortModel
          .filter(({ field }) =>
            ["id", "txnId", "status", "amount", "sno"].includes(field)
          )
          .map(({ field, sort }) => {
            if (field === "sno") return { id: sort.toLowerCase() }; // sort by id for sno
            return { [field]: sort.toLowerCase() };
          });
      } catch (err) {
        console.error("Invalid sort JSON", err);
      }
    }
    if (orderBy.length === 0) orderBy = [{ id: "asc" }];

    // ===== Filtering =====
    const where = { studentId };
    if (req.query.filter) {
      try {
        const filterModel = JSON.parse(req.query.filter);
        const AND = [];

        filterModel.items?.forEach(({ field, operator, value }) => {
          if (!value) return;

          switch (field) {
            case "txnId":
              if (operator === "contains") {
                AND.push({ txnId: { contains: value, mode: "insensitive" } });
              }
              break;
            case "status":
              AND.push({ status: value });
              break;
            case "sno":
              if (!isNaN(Number(value))) {
                const snoNum = Number(value);
                AND.push({ id: snoNum });
              }
              break;
            case "amount":
              if (!isNaN(Number(value))) {
                AND.push({ amount: Number(value) });
              }
              break;
          }
        });

        if (AND.length > 0) where.AND = AND;
      } catch (err) {
        console.error("Invalid filter JSON", err);
      }
    }

    // ===== Fetch total count and paginated enrollments =====
    const [enrollments, total] = await Promise.all([
      prisma.enrollment.findMany({
        where,
        skip: page * pageSize,
        take: pageSize,
        orderBy,
        include: {
          subject: {
            include: {
              teacher: {
                select: {
                  firstName: true,
                  lastName: true,
                },
              },
            },
          },
        },
      }),
      prisma.enrollment.count({ where }),
    ]);

    // ===== Format results =====
    const formatted = enrollments.map((e, index) => ({
      ...e,
      sno: page * pageSize + index + 1,
      subject: {
        id: e.subject.id,
        title: e.subject.title,
        description: e.subject.description,
        thumbnailUrl: e.subject.thumbnailUrl || "/default-thumbnail.png",
        teacherName: e.subject.teacher
          ? `${e.subject.teacher.firstName} ${e.subject.teacher.lastName}`
          : "Unknown Teacher",
      },
    }));

    res.json({ rows: formatted, total });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};
