package com.eactive.httpmockserver.server.controller;

import com.eactive.httpmockserver.server.dto.ServerDTO;
import com.eactive.httpmockserver.server.dto.ServerSearch;
import com.eactive.httpmockserver.server.entity.Server;
import com.eactive.httpmockserver.server.mapper.ServerMapper;
import com.eactive.httpmockserver.server.service.ServerMgmtService;
import org.apache.commons.lang3.StringUtils;
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 java.util.List;


@Controller
@RequestMapping("/mgmt/servers")
public class ServerMgmtController {

    private final ServerMgmtService serverMgmtService;

    private final ServerMapper serverMapper;

    private final Validator validator;

    public ServerMgmtController(ServerMgmtService serverMgmtService, ServerMapper serverMapper, Validator validator) {
        this.serverMgmtService = serverMgmtService;
        this.serverMapper = serverMapper;
        this.validator = validator;
    }

    public static final String SERVER = "server";

    public static final String SERVER_EDIT = "page/servers/serverEdit";

    public static final String SERVER_LIST_VIEW = "redirect:/mgmt/servers/list_view.do";

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

        Page<Server> page = serverMgmtService.findAll(serverSearch.buildSpecification(), pageable);
        model.addAttribute("page", page);
        model.addAttribute("pageable", pageable);
        model.addAttribute("modelSearch", serverSearch);

        return "page/servers/serverList";
    }

    @GetMapping("/create_view.do")
    public String createView(ModelMap model) {
        ServerDTO defaultServer = new ServerDTO();
        model.addAttribute(SERVER, defaultServer);
        return SERVER_EDIT;
    }

    @GetMapping("/update_view.do")
    public String updateView(ModelMap model, @RequestParam("id") Long id) {
        Server found = serverMgmtService.findById(id);
        ServerDTO server = serverMapper.map(found);
        model.addAttribute(SERVER, server);
        return SERVER_EDIT;
    }

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

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

        validator.validate(dto, bindingResult);

        if (bindingResult.hasErrors()) {
            model.addAttribute(SERVER, dto);
            return SERVER_EDIT;
        }

        Server server = serverMapper.map(dto);
        serverMgmtService.create(server);
        return SERVER_LIST_VIEW;
    }

    @PostMapping("/update.do")
    public String update(@ModelAttribute(SERVER) ServerDTO dto,
                         BindingResult bindingResult,
                         ModelMap model) {

        if (StringUtils.isEmpty(dto.getId().toString())) {
            return SERVER_LIST_VIEW;
        }

        validator.validate(dto, bindingResult);

        if (bindingResult.hasErrors()) {
            model.addAttribute(SERVER, dto);
            return SERVER_EDIT;
        }

        Server updated = serverMapper.map(dto);
        serverMgmtService.update(dto.getId(), updated);
        return SERVER_LIST_VIEW;
    }

    @PostMapping("/delete.do")
    public String delete(@RequestParam("checkedIdForDel") List<String> checkedIdForDel) {
        for (String id : checkedIdForDel) {
            serverMgmtService.delete(Long.parseLong(id));
        }
        return SERVER_LIST_VIEW;
    }


}
