import { Request, Response } from "express";
import * as quizResultService from "../services/quizResultService";
import { sendResponse, handleError } from "../utils/apiResponse";

// @desc    User submits quiz answers
// @route   POST /api/quizzes/:id/submit
export const submitQuiz = async (
  req: Request,
  res: Response,
): Promise<void> => {
  try {
    let { answers } = req.body as { answers?: unknown[] };
    // Accept empty or missing answers array for partial/timeout submissions
    if (!answers || !Array.isArray(answers)) {
      answers = [];
    }
    const isValidAnswer = (
      a: unknown,
    ): a is { question_id: string; selected_option: string } =>
      typeof a === "object" &&
      a !== null &&
      typeof (a as Record<string, unknown>).question_id === "string" &&
      typeof (a as Record<string, unknown>).selected_option === "string";

    if (!answers.every(isValidAnswer)) {
      return sendResponse(res, 400, "Invalid answer format");
    }
    const result = await quizResultService.submitQuiz(
      req.params.id as string,
      req.user!.id,
      answers,
    );
    sendResponse(res, 201, "Quiz submitted successfully", {
      result,
      totalQuestions: result.totalQuestions,
    });
  } catch (error) {
    handleError(res, error);
  }
};

// @desc    User gets their own quiz result history
// @route   GET /api/quizzes/my-results
export const getMyResults = async (
  req: Request,
  res: Response,
): Promise<void> => {
  try {
    const results = await quizResultService.getMyResults(req.user!.id);
    sendResponse(res, 200, "Results fetched", { results });
  } catch (error) {
    handleError(res, error);
  }
};

// @desc    Admin gets all results for a quiz
// @route   GET /api/quizzes/:id/results
export const getQuizResults = async (
  req: Request,
  res: Response,
): Promise<void> => {
  try {
    const { quiz, results } = await quizResultService.getQuizResults(
      req.params.id as string,
    );
    sendResponse(res, 200, "Quiz results fetched", {
      quiz,
      count: results.length,
      results,
    });
  } catch (error) {
    handleError(res, error);
  }
};

// @desc    Admin gets a single user's full submission for a quiz
// @route   GET /api/quizzes/:quizId/submissions/:userId
export const getSubmission = async (
  req: Request,
  res: Response,
): Promise<void> => {
  try {
    const submission = await quizResultService.getSubmission(
      req.params.quizId as string,
      req.params.userId as string,
    );
    sendResponse(res, 200, "Submission fetched", { submission });
  } catch (error) {
    handleError(res, error);
  }
};

// @desc    Admin exports quiz results as CSV
// @route   GET /api/quizzes/:id/results/export
export const exportResults = async (
  req: Request,
  res: Response,
): Promise<void> => {
  try {
    const { csv, filename } = await quizResultService.exportResultsCSV(
      req.params.id as string,
    );
    res.setHeader("Content-Type", "text/csv");
    res.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
    res.status(200).send(csv);
  } catch (error) {
    handleError(res, error);
  }
};
