import { Router } from "express";
import { RecipeRepository } from "../../repositories/RecipeRepository.js";
import { RecipeDtoEntityMapper } from "../../mappers/RecipeDtoEntityMapper.js";
import { RecipeHandler } from "../../handlers/RecipeHandler.js";
import { asyncHandler } from "../../utils/asyncHandler.js";
import { RecipeDto } from "../dtos/RecipeDto.js";
import { RecipeIngredientDtoEntityMapper } from "../../mappers/RecipeIngredientDtoEntityMapper.js";
import { RecipeIngredientGroupDtoEntityMapper } from "../../mappers/RecipeIngredientGroupDtoEntityMapper.js";
import { RecipeInstructionStepDtoEntityMapper } from "../../mappers/RecipeInstructionStepDtoEntityMapper.js";
import {HttpStatusCode} from "../apiHelpers/HttpStatusCodes.js";
import {TagDtoEntityMapper} from "../../mappers/TagDtoEntityMapper.js";

export const recipeBasicRoute = "/recipe";
/**
 * Handles all recipe related routes
 */
const router = Router();

// Inject repo + mapper here
const recipeRepository = new RecipeRepository();
const recipeIngredientMapper = new RecipeIngredientDtoEntityMapper();
const recipeIngredientGroupMapper = new RecipeIngredientGroupDtoEntityMapper(recipeIngredientMapper);
const recipeInstructionStepMapper = new RecipeInstructionStepDtoEntityMapper();
const tagMapper = new TagDtoEntityMapper();
const recipeMapper = new RecipeDtoEntityMapper(recipeInstructionStepMapper, recipeIngredientGroupMapper, tagMapper);
const recipeHandler = new RecipeHandler(recipeRepository, recipeMapper);


/**
 * Save or update recipe. 
 * Consumes: RecipeDto
 * Responds with RecipeDto as saved in database
 * A new recipe is created if the dto doesn't contain an ID. Otherwise, the
 * existing recipe is updated. Throws an exception if the dto does contain an
 * ID that's not present in the database
 */
router.post(
  "/create-or-update",
  asyncHandler(async(req, res) => {
    const requestDto: RecipeDto = req.body;
    const responseDto = await recipeHandler.createOrUpdateRecipe(requestDto);
    res.status(HttpStatusCode.CREATED).json(responseDto);
  })
)

/**
 * Load recipe by id
 * Responds with RecipeDto
 */
router.get(
  "/:id",
  asyncHandler(async(req, res) => {
    const id = req.params.id;
    const responseDto = await recipeHandler.getRecipeById(id);
    res.status(HttpStatusCode.OK).json(responseDto);
  })
);

export default router;