package com.eactive.httpmockserver.api.controller;

import com.eactive.httpmockserver.api.dto.MockResponseDTO;
import com.eactive.httpmockserver.api.dto.MockRouteDTO;
import com.eactive.httpmockserver.api.dto.MockRouteSearch;
import com.eactive.httpmockserver.api.entity.MockRoute;
import com.eactive.httpmockserver.api.mapper.MockRouteMapper;
import com.eactive.httpmockserver.api.service.MockRouteService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;

@Controller
@RequestMapping("/mgmt/routes")
public class MockRouteMgmtController {

    @PostConstruct
    public void init() {
        mockRouteService.initAllRoutes();
    }

    @Autowired
    private MockRouteService mockRouteService;

    @Autowired
    private Validator validator;

    @Autowired
    private MockRouteMapper mockRouteMapper;

    public static final String MOCK_ROUTE_EDIT = "page/routes/mockRouteEdit";
    public static final String MOCK_ROUTE_LIST_VIEW = "redirect:/mgmt/routes/list_view.do";

    @GetMapping("/list_view.do")
    public String listView(@ModelAttribute("mockRouteSearch") MockRouteSearch mockRouteSearch, ModelMap model, Pageable pageable) {

        Page<MockRoute> page = mockRouteService.findAll(mockRouteSearch.buildSpecification(), pageable);
        model.addAttribute("page", page);
        model.addAttribute("pageable", pageable);
        model.addAttribute("modelSearch", mockRouteSearch);

        return "page/routes/mockRouteList";
    }

    @GetMapping("/create_view.do")
    public String createView(ModelMap model) {
        MockRouteDTO defaultRoute = new MockRouteDTO();
        MockResponseDTO defaultResponse = new MockResponseDTO();
        defaultResponse.setDefaultResponse("true");
        defaultRoute.getResponses().add(defaultResponse);
        model.addAttribute("mockRoute", defaultRoute);
        return MOCK_ROUTE_EDIT;
    }

    @GetMapping("/update_view.do")
    public String updateView(ModelMap model, @RequestParam("id") Long id) {

        MockRoute found = mockRouteService.findById(id);

        model.addAttribute("mockRoute", mockRouteMapper.map(found));
        return MOCK_ROUTE_EDIT;
    }

    @PostMapping("/register.do")
    public String register(@ModelAttribute("mockRoute") MockRouteDTO dto, BindingResult bindingResult, ModelMap model) {

        if (dto == null) {
            return "redirect:/mgmt/routes/create_view.do";
        }

        validator.validate(dto, bindingResult);

        if (bindingResult.hasErrors()) {
            model.addAttribute("mockRoute", dto);
            return MOCK_ROUTE_EDIT;
        }

        MockRoute mockRoute = mockRouteMapper.map(dto);
        mockRouteService.create(mockRoute);
        mockRouteService.initAllRoutes();
        return MOCK_ROUTE_LIST_VIEW;
    }


    @PostMapping("/update.do")
    public String update(@RequestParam("id") String id,
                         @ModelAttribute("mockRoute") MockRouteDTO dto,
                         BindingResult bindingResult, ModelMap model) {

        if (StringUtils.isEmpty(id)) {
            return MOCK_ROUTE_LIST_VIEW;
        }

        validator.validate(dto, bindingResult);

        if (bindingResult.hasErrors()) {
            model.addAttribute("mockRoute", dto);
            return MOCK_ROUTE_EDIT;
        }

        MockRoute mockRoute = mockRouteMapper.map(dto);
        mockRouteService.update(Long.parseLong(id), mockRoute);
        mockRouteService.initAllRoutes();
        return MOCK_ROUTE_LIST_VIEW;
    }


    @PostMapping("/delete.do")
    public String delete(@ModelAttribute MockRouteSearch modelSearch) {
        modelSearch.getCheckedIdForDel().forEach(id -> {
            mockRouteService.deleteById(Long.parseLong(id));
        });
        mockRouteService.initAllRoutes();
        return MOCK_ROUTE_LIST_VIEW;
    }
}
