const QuizQuestion = require("../../models/questionModel");
const UserAnswer = require("../../models/gameAnswerModel");
const User = require("../../models/userModel");
const PDFDocument = require("pdfkit");
const fs = require("fs");
const path = require("path");
const puppeteer = require("puppeteer");
const os = require("os");
const axios = require("axios");
exports.submitAnswer = async (req, res) => {
  const userId = req.user?.id;
  const { questionId, answer } = req.body;

  if (!questionId || !answer) {
    return res
      .status(400)
      .json({ success: false, message: "Question ID and answer are required" });
  }

  try {
    const question = await QuizQuestion.findById(questionId);
    if (!question) {
      return res
        .status(404)
        .json({ success: false, message: "Question not found" });
    }

    if (!question.options.includes(answer)) {
      return res.status(400).json({
        success: false,
        message: `Invalid answer. Allowed options are: ${question.options.join(
          ", "
        )}`,
      });
    }

    const existingAnswer = await UserAnswer.findOne({
      user: userId,
      question: questionId,
    });

    if (existingAnswer) {
      existingAnswer.answer = answer;
      await existingAnswer.save();
      return res.status(200).json({
        success: true,
        message: "Answer updated successfully",
        data: existingAnswer,
      });
    }

    const newAnswer = new UserAnswer({
      user: userId,
      question: questionId,
      answer,
    });

    await newAnswer.save();

    res.status(201).json({
      success: true,
      message: "Answer submitted successfully",
      data: newAnswer,
    });
  } catch (err) {
    console.error("Submit Answer Error:", err);
    res.status(500).json({ success: false, message: "Server Error" });
  }
};

exports.generatePdfReport = async (req, res) => {
  const userId = req.user?.id;

  try {
    const user = await User.findById(userId);
    const answers = await UserAnswer.find({ user: userId }).populate(
      "question"
    );

    if (!answers.length) {
      return res
        .status(400)
        .json({ success: false, message: "No answers found" });
    }

    let score = 0;
    const answerPoints = {
      "Almost Always": 1,
      Often: 2,
      Sometimes: 3,
      Rarely: 4,
    };

    answers.forEach((ans) => {
      score += answerPoints[ans.answer] || 0;
    });

    const maxScore = answers.length * 4;
    const minScore = answers.length * 1;

    let interpretation = "Needs Care";
    if (score >= 24) interpretation = "Thriving";
    else if (score >= 18) interpretation = "Balanced";

    const reportsDir = path.join(__dirname, "../../reports");
    if (!fs.existsSync(reportsDir)) {
      fs.mkdirSync(reportsDir, { recursive: true });
    }

    const fileName = `mental_health_report_${user._id}.pdf`;
    const filePath = path.join(reportsDir, fileName);

    const doc = new PDFDocument();
    const stream = fs.createWriteStream(filePath);
    doc.pipe(stream);

    doc.fontSize(20).text("Mental Health Report", { align: "center" });
    doc.moveDown();

    doc.fontSize(14).text(`Name: ${user.fullname}`);
    doc.text(`Email: ${user.email}`);
    doc.text(`Generated: ${new Date().toLocaleString()}`);
    doc.moveDown();

    doc.fontSize(16).text("Summary", { underline: true });
    doc.moveDown(0.5);
    doc.fontSize(14).text(`Total Questions: ${answers.length}`);
    doc.text(`Score: ${score} / ${maxScore}`);
    doc.text(`Interpretation: ${interpretation}`);
    doc.moveDown();

    doc.fontSize(16).text("Question-wise Summary", { underline: true });
    answers.forEach((ans, index) => {
      doc.fontSize(12).text(`${index + 1}. ${ans.question.question}`);
      doc
        .font("Helvetica-Bold")
        .text(`→ Your Answer: ${ans.answer}`, { indent: 20 });
      doc.moveDown(0.5);
    });

    doc.end();

    stream.on("finish", () => {
      res.status(200).json({
        success: true,
        message: "Report generated successfully",
        url: `/reports/${fileName}`,
      });
    });
  } catch (err) {
    console.error("PDF Report Error:", err);
    res.status(500).json({ success: false, message: "Server Error" });
  }
};

exports.getScoreSummary = async (req, res) => {
  const userId = req.user?.id;

  try {
    const answers = await UserAnswer.find({ user: userId }).populate(
      "question"
    );

    if (!answers.length) {
      return res.status(400).json({
        success: false,
        message: "No answers found",
      });
    }

    const answerPoints = {
      "Almost Always": 1,
      Often: 2,
      Sometimes: 3,
      Rarely: 4,
    };

    let totalScore = 0;
    let anxietyScore = 0;
    let stressScore = 0;
    let depressionScore = 0;

    answers.forEach((ans, index) => {
      const point = answerPoints[ans.answer] || 0;
      totalScore += point;

      if (index < 7) anxietyScore += point;
      else if (index < 14) stressScore += point;
      else depressionScore += point;
    });

    // Define all possible summary labels and their messages
    const scoreSummaries = {
      Thriving:
        "You're doing really well. Keep nurturing yourself. Therapy can still deepen your self-awareness and personal growth.",
      Balanced:
        "You're managing most things with grace. Therapy can support you in staying aligned and growing.",
      "Needs Care":
        "You might be feeling a little off lately, and that's okay. Therapy can offer a compassionate space to reflect, heal, and reset.",
    };

    // Determine which label applies
    let scoreLabel = "";
    if (totalScore >= 24) scoreLabel = "Thriving";
    else if (totalScore >= 18) scoreLabel = "Balanced";
    else scoreLabel = "Needs Care";

    // Helper to interpret each category
    const interpret = (score) => {
      if (score >= 24) return "High";
      if (score >= 18) return "Moderate";
      return "Low";
    };

    res.status(200).json({
      success: true,
      totalScore,
      scoreLabel, // e.g., "Thriving"
      scoreMessage: scoreSummaries[scoreLabel], // The text for the current score
      allMessages: scoreSummaries, // Contains all possible messages, frontend can use if needed
      details: {
        anxiety: {
          score: anxietyScore,
          level: interpret(anxietyScore),
        },
        stress: {
          score: stressScore,
          level: interpret(stressScore),
        },
        depression: {
          score: depressionScore,
          level: interpret(depressionScore),
        },
      },
    });
  } catch (err) {
    console.error("Score Summary Error:", err);
    res.status(500).json({ success: false, message: "Server Error" });
  }
};

exports.getQuestions = async (req, res) => {
  try {
    const questions = await QuizQuestion.find();
    res.status(200).json({ success: true, data: questions });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: "Failed to fetch questions",
      error: error.message,
    });
  }
};

// Load images from the "public" folder (if needed)
const getBase64Image = (filePath) => {
  try {
    if (!fs.existsSync(filePath)) {
      console.error(`File not found: ${filePath}`);
      return null;
    }
    const imageBuffer = fs.readFileSync(filePath);
    return `data:image/png;base64,${imageBuffer.toString("base64")}`;
  } catch (error) {
    console.error(`Error loading image: ${filePath}`, error);
    return null;
  }
};

exports.generatePdf = async (req, res) => {
  const { url, token } = req.body;

  if (!url) {
    return res
      .status(400)
      .json({ error: "URL is required in the request body" });
  }
  if (!token) {
    return res
      .status(400)
      .json({ error: "Token is required in the request body" });
  }

  try {
    const browser = await puppeteer.launch({
      headless: true,
      args: ["--no-sandbox", "--disable-setuid-sandbox"],
    });

    const page = await browser.newPage();

    // Set the token in localStorage before any scripts run
    await page.goto("about:blank");
    await page.evaluateOnNewDocument((t) => {
      window.localStorage.setItem("token", t);
    }, token);

    // Now go to the real URL
    await page.goto(url, { waitUntil: "networkidle2" });

    // Wait for 1 second to ensure dynamic content loads
    await new Promise((resolve) => setTimeout(resolve, 1000));

    const tempFilePath = path.join(os.tmpdir(), `report-${Date.now()}.pdf`);

    await page.pdf({
      path: tempFilePath,
      format: "A4",
      printBackground: true,
      margin: { top: "0px", bottom: "0px", left: "0px", right: "0px" },
    });

    await browser.close();

    const pdfBuffer = fs.readFileSync(tempFilePath);
    fs.unlinkSync(tempFilePath);

    res.setHeader("Content-Type", "application/pdf");
    res.setHeader("Content-Disposition", `attachment; filename=report.pdf`);
    res.status(200).send(pdfBuffer);
  } catch (error) {
    console.error("Error generating PDF:", error);
    res.status(500).json({ error: "Error generating PDF" });
  }
};

const apiToken = "2SZe0vjxHHWklE70d2f269c287c62c78c44348b7efcd7e2f0";
const urlToConvert = "https://kp2wh2g7-5173.inc1.devtunnels.ms/game-report";
// exports.generatePDFServerless = async (req, res) => {
//   try {
//     const response = await axios({
//       method: "POST",
//       url: `https://production-sfo.browserless.io/pdf?token=${apiToken}`,
//       headers: {
//         "Content-Type": "application/json",
//         "Cache-Control": "no-cache",
//       },
//       data: {
//         url: urlToConvert,
//         options: {
//           format: "A4", // Use A4 or letter unless you truly need A0
//           printBackground: true, // Ensures styles like background colors show
//           displayHeaderFooter: false, // Set to false to print exactly as-is
//           preferCSSPageSize: true, // Use @page CSS if defined
//           margin: { top: "0px", right: "0px", bottom: "0px", left: "0px" }, // No margin
//           scale: 1, // 1 = 100% scale
//           timeout: 30000, // Optional: increase timeout if needed
//         },
//       },
//       responseType: "arraybuffer", // Binary PDF
//     });

//     res.set({
//       "Content-Type": "application/pdf",
//       "Content-Disposition": "attachment; filename=output.pdf",
//       "Content-Length": response.data.length,
//     });

//     res.send(response.data);
//   } catch (err) {
//     console.error("❌ Error generating PDF:", err.message);
//     res
//       .status(500)
//       .json({ message: "Error generating PDF", error: err.message });
//   }
// };
exports.generatePDFServerless = async (req, res) => {
  const { url, token } = req.body;

  if (!url) {
    return res
      .status(400)
      .json({ error: "URL is required in the request body" });
  }
  if (!token) {
    return res
      .status(400)
      .json({ error: "Token is required in the request body" });
  }

  try {
    // Prepare the script to set the token in localStorage before page loads
    const setTokenScript = `
      window.localStorage.setItem('token', '${token.replace(/'/g, "\\'")}');
    `;

    const response = await axios({
      method: "POST",
      url: `https://production-sfo.browserless.io/pdf?token=${apiToken}`,
      headers: {
        "Content-Type": "application/json",
        "Cache-Control": "no-cache",
      },
      data: {
        url: url,
        gotoOptions: {
          waitUntil: "networkidle2",
        },
        options: {
          format: "A4",
          printBackground: true,
          displayHeaderFooter: false,
          preferCSSPageSize: true,
          margin: { top: "0px", right: "0px", bottom: "0px", left: "0px" },
          scale: 1,
          timeout: 30000,
        },
        // This is the key part!
        // This code runs before any scripts on the page
        // See: https://docs.browserless.io/docs/pdf.html#customizing-the-page
        // Use 'code' or 'waitFor' or 'gotoOptions'
        // 'code' runs in the page context before rendering
        // Here, we set localStorage token before loading the real page
        // Browserless will run this code before navigating to the URL
        // The `code` property is preferred to `evaluate` or `evaluateOnNewDocument`
        // as it runs before navigation
        code: setTokenScript,
      },
      responseType: "arraybuffer",
    });

    res.set({
      "Content-Type": "application/pdf",
      "Content-Disposition": "attachment; filename=output.pdf",
      "Content-Length": response.data.length,
    });

    res.send(response.data);
  } catch (err) {
    console.error("❌ Error generating PDF:", err.message);
    res
      .status(500)
      .json({ message: "Error generating PDF", error: err.message });
  }
};
