const prisma = require("../lib/prisma");
const {
  notifyUser,
  notifyManyUsers,
} = require("../services/notification.service");

/**
 * =========================
 * USER (Student / Teacher)
 * =========================
 */

// Submit feedback
exports.submitFeedback = async (req, res) => {
  try {
    const userId = req.user.id;
    const role = req.user.role; // student | teacher
    const { message } = req.body;

    if (!message || !message.trim()) {
      return res.status(400).json({ message: "Feedback message is required" });
    }

    const feedback = await prisma.feedback.create({
      data: {
        userId,
        role,
        message: message.trim(),
      },
    });

    // Notify all admins
    const admins = await prisma.user.findMany({
      where: { role: "admin" },
      select: { id: true },
    });

    const adminIds = admins.map((a) => a.id);

    if (adminIds.length > 0) {
      await notifyManyUsers(
        req,
        adminIds,
        `New feedback submitted by ${role}`,
        null // optional: sender is the user who submitted feedback
      );
    }

    res.json({
      message: "Feedback submitted successfully",
      feedback,
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};

/**
 * =========================
 * ADMIN
 * =========================
 */

// Get feedback stats (cards)
exports.getFeedbackStats = async (req, res) => {
  try {
    const [total, unread, highlighted] = await Promise.all([
      prisma.feedback.count(),
      prisma.feedback.count({ where: { isRead: false } }),
      prisma.feedback.count({ where: { isHighlighted: true } }),
    ]);

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

// Get feedback list (with filters & pagination)
exports.getFeedbacks = async (req, res) => {
  try {
    const page = Number(req.query.page) || 0;
    const pageSize = Number(req.query.pageSize) || 10;

    const { type } = req.query;
    // type = all | unread | highlighted

    let where = {};

    if (type === "unread") {
      where.isRead = false;
    }

    if (type === "highlighted") {
      where.isHighlighted = true;
    }

    const total = await prisma.feedback.count({ where });

    const feedbacks = await prisma.feedback.findMany({
      skip: page * pageSize,
      take: pageSize,
      where,
      orderBy: { createdAt: "desc" },
      include: {
        user: {
          select: {
            firstName: true,
            lastName: true,
            role: true,
          },
        },
      },
    });

    const rows = feedbacks.map((f, index) => ({
      id: f.id,
      sno: page * pageSize + index + 1,
      userName: `${f.user.firstName} ${f.user.lastName}`,
      role: f.role,
      message: f.message,
      isRead: f.isRead,
      isHighlighted: f.isHighlighted,
      adminReply: f.adminReply,
      submittedAt: f.createdAt,
    }));

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

// Get feedback by ID (mark as read)
exports.getFeedbackById = async (req, res) => {
  try {
    const id = Number(req.params.id);

    const feedback = await prisma.feedback.findUnique({
      where: { id },
      include: {
        user: {
          select: {
            firstName: true,
            lastName: true,
            email: true,
            role: true,
          },
        },
      },
    });

    if (!feedback) {
      return res.status(404).json({ message: "Feedback not found" });
    }

    // Mark as read if unread
    if (!feedback.isRead) {
      await prisma.feedback.update({
        where: { id },
        data: { isRead: true },
      });
    }

    res.json({
      ...feedback,
      userName: `${feedback.user.firstName} ${feedback.user.lastName}`,
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};

exports.markFeedbackAsRead = async (req, res) => {
  try {
    const id = Number(req.params.id);

    const feedback = await prisma.feedback.findUnique({
      where: { id },
    });

    if (!feedback) {
      return res.status(404).json({ message: "Feedback not found" });
    }

    if (!feedback.isRead) {
      const updated = await prisma.feedback.update({
        where: { id },
        data: { isRead: true },
      });

      return res.json({
        message: "Feedback marked as read",
        feedback: updated,
      });
    }

    // Already read
    res.json({ message: "Feedback already read", feedback });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};

// Highlight / Unhighlight feedback
exports.toggleHighlightFeedback = async (req, res) => {
  try {
    const id = Number(req.params.id);
    const { isHighlighted } = req.body;

    const feedback = await prisma.feedback.update({
      where: { id },
      data: { isHighlighted },
    });

    res.json({
      message: isHighlighted
        ? "Feedback highlighted"
        : "Feedback unhighlighted",
      feedback,
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};

// Reply to feedback
exports.replyToFeedback = async (req, res) => {
  try {
    const id = Number(req.params.id);
    const { reply } = req.body;

    if (!reply || !reply.trim()) {
      return res.status(400).json({ message: "Reply message is required" });
    }

    const feedback = await prisma.feedback.update({
      where: { id },
      data: {
        adminReply: reply.trim(),
        repliedAt: new Date(),
        isRead: true,
      },
    });

    // Notify the feedback submitter
    if (feedback.userId) {
      await notifyUser(
        req,
        feedback.userId,
        `Your feedback has been replied by admin`,
        null
      );
    }

    res.json({
      message: "Reply sent successfully",
      feedback,
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};

/**
 * =========================
 * USER (Student / Teacher)
 * =========================
 */

// Get my feedbacks
exports.getMyFeedbacks = async (req, res) => {
  try {
    const userId = req.user.id;

    // Pagination query params
    const page = parseInt(req.query.page) || 1;       // default page 1
    const pageSize = parseInt(req.query.pageSize) || 10; // default 10 per page
    const skip = (page - 1) * pageSize;

    // Fetch feedbacks and total count in parallel
    const [feedbacks, total] = await Promise.all([
      prisma.feedback.findMany({
        where: { userId },
        orderBy: { createdAt: "desc" },
        skip,
        take: pageSize,
        select: {
          id: true,
          message: true,
          adminReply: true,
          isRead: true,
          isHighlighted: true,
          createdAt: true,
          repliedAt: true,
        },
      }),
      prisma.feedback.count({
        where: { userId },
      }),
    ]);

    res.json({
      feedbacks,
      total,
      page,
      pageSize,
      totalPages: Math.ceil(total / pageSize),
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};

/**
 * =========================
 * PUBLIC
 * =========================
 */

// Get highlighted testimonials
exports.getTestimonials = async (req, res) => {
  try {
    const testimonials = await prisma.feedback.findMany({
      where: {
        isHighlighted: true,
      },
      orderBy: { createdAt: "desc" }, // most recent first
      take: 6, // only the latest 6
      include: {
        user: {
          select: {
            firstName: true,
            lastName: true,
            role: true,
          },
        },
      },
    });

    const data = testimonials.map((f) => ({
      id: f.id,
      userName: `${f.user.firstName} ${f.user.lastName}`,
      role: f.role,
      message: f.message,
      createdAt: f.createdAt,
    }));

    res.json(data); // send array directly, no need to wrap in { testimonials: ... }
  } catch (err) {
    console.error(err);
    res.status(500).json({ message: "Server error" });
  }
};