import { Request, Response } from "express";
import {
  getSudokuPuzzleService,
  startSudokuAttemptService,
  updateSudokuAttemptService,
  submitSudokuAttemptService,
  getMySudokuAttemptsService,
  getRandomSudokuPuzzleService
} from "../services/sudokuService";
import mongoose from "mongoose";
import { sendResponse, handleError } from "../utils/apiResponse";

export const getSudokuPuzzle = async (req: Request, res: Response) => {
  try {
    // Ignore difficulty, always return a random puzzle from all difficulties
    const puzzle = await getRandomSudokuPuzzleService();
    if (!puzzle) {
      return sendResponse(res, 404, "No puzzles available");
    }
    sendResponse(res, 200, "Sudoku puzzle fetched", { puzzle });
  } catch (error) {
    handleError(res, error);
  }
};

export const startSudokuAttempt = async (req: Request, res: Response) => {
  try {
    const userId = new mongoose.Types.ObjectId(req.user!.id);
    let { gameId } = req.body;
    if (Array.isArray(gameId)) gameId = gameId[0];
    // Validate gameId presence and format
    if (!gameId || !mongoose.Types.ObjectId.isValid(gameId)) {
      return sendResponse(res, 400, "Invalid or missing gameId");
    }
    const result = await startSudokuAttemptService(
      userId,
      new mongoose.Types.ObjectId(gameId),
    );
    sendResponse(res, 201, "Sudoku attempt started", result);
  } catch (error) {
    handleError(res, error);
  }
};

export const updateSudokuAttempt = async (req: Request, res: Response) => {
  try {
    let { attemptId } = req.params;
    const { answers } = req.body;
    if (Array.isArray(attemptId)) attemptId = attemptId[0];
    const attempt = await updateSudokuAttemptService(
      new mongoose.Types.ObjectId(attemptId),
      answers,
    );
    sendResponse(res, 200, "Sudoku attempt updated", { attempt });
  } catch (error) {
    handleError(res, error);
  }
};

export const submitSudokuAttempt = async (req: Request, res: Response) => {
  try {
    let { attemptId } = req.params;
    const userId = new mongoose.Types.ObjectId(req.user!.id);
    const { answers } = req.body;
    if (Array.isArray(attemptId)) attemptId = attemptId[0];
    const result = await submitSudokuAttemptService(
      new mongoose.Types.ObjectId(attemptId),
      userId,
      answers,
    );
    sendResponse(res, 200, "Sudoku attempt submitted", result);
  } catch (error) {
    handleError(res, error);
  }
};

export const getMySudokuAttempts = async (req: Request, res: Response) => {
  try {
    const userId = new mongoose.Types.ObjectId(req.user!.id);
    const attempts = await getMySudokuAttemptsService(userId);
    sendResponse(res, 200, "Sudoku attempts fetched", { attempts });
  } catch (error) {
    handleError(res, error);
  }
};
