package dev.fyloz.trial.colorrecipesexplorer.web.controller.thymeleaf;

import dev.fyloz.trial.colorrecipesexplorer.exception.TooLowQuantityException;
import dev.fyloz.trial.colorrecipesexplorer.web.response.JSONResponseBuilder;
import dev.fyloz.trial.colorrecipesexplorer.web.response.ModelResponseBuilder;
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseCode;
import dev.fyloz.trial.colorrecipesexplorer.web.response.ResponseDataType;
import dev.fyloz.trial.colorrecipesexplorer.model.dto.InventoryDto;
import dev.fyloz.trial.colorrecipesexplorer.service.InventoryService;
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialJavaService;
import dev.fyloz.trial.colorrecipesexplorer.service.model.MaterialTypeJavaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;
import java.util.Map;

import static dev.fyloz.trial.colorrecipesexplorer.web.StringBank.RESPONSE_REASON;
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.INVENTORY;
import static dev.fyloz.trial.colorrecipesexplorer.web.WebsitePaths.USE_INVENTORY;

@Controller
@Profile("thymeleaf")
public class InventoryController {

    private InventoryService inventoryService;
    private MaterialJavaService materialService;
    private MaterialTypeJavaService materialTypeService;

    @Autowired
    public InventoryController(InventoryService inventoryService, MaterialJavaService materialService, MaterialTypeJavaService materialTypeService) {
        this.inventoryService = inventoryService;
        this.materialService = materialService;
        this.materialTypeService = materialTypeService;
    }

    @GetMapping(INVENTORY)
    public ModelAndView getPage(ModelAndView model) {
        return new ModelResponseBuilder(model)
                .withView(INVENTORY)
                .addResponseData(ResponseDataType.MATERIALS, materialService.getAllNotMixType())
                .addResponseData(ResponseDataType.MATERIAL_TYPES, materialTypeService.getAll())
                .build();
    }

    @PostMapping(value = USE_INVENTORY, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @Transactional
    public Map<String, Object> consumeMaterials(@RequestBody List<InventoryDto> mixes) {
        JSONResponseBuilder jsonResponseBuilder = new JSONResponseBuilder();

        try {
            inventoryService.use(mixes);

            jsonResponseBuilder.addResponseCode(ResponseCode.SUCCESS_USING_MATERIALS);
        } catch (TooLowQuantityException ex) {
            jsonResponseBuilder.addResponseCode(ResponseCode.NOT_ENOUGH_MATERIAL, ex.getMaterial().getName())
                    .addAttribute(RESPONSE_REASON, ex.getResponse());
        }

        return jsonResponseBuilder.build();
    }
}
