package com.eactive.httpmockserver.user.controller;

import com.eactive.httpmockserver.common.util.SecurityUtil;
import com.eactive.httpmockserver.user.dto.UserRegisterDTO;
import com.eactive.httpmockserver.user.dto.UserSearch;
import com.eactive.httpmockserver.user.dto.UserUpdateDTO;
import com.eactive.httpmockserver.user.entity.StaffUser;
import com.eactive.httpmockserver.user.mapper.StaffUserMapper;
import com.eactive.httpmockserver.user.service.StaffUserService;
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.*;

@Controller
@RequestMapping("/mgmt/users")
public class UserMgmtController {

    public static final String STAFF_USER_EDIT = "page/users/staffUserEdit";
    public static final String USERS_LIST_VIEW = "redirect:/mgmt/users/list_view.do";

    private final StaffUserService staffUserService;

    private final Validator validator;

    private final StaffUserMapper staffUserMapper;

    public UserMgmtController(StaffUserService staffUserService, Validator validator, StaffUserMapper staffUserMapper) {
        this.staffUserService = staffUserService;
        this.validator = validator;
        this.staffUserMapper = staffUserMapper;
    }

    @GetMapping("/list_view.do")
    public String userList(@ModelAttribute("userSearch") UserSearch userSearch,
                           ModelMap model,
                           Pageable pageable) {

        Page<StaffUser> page = staffUserService.findAll(userSearch.buildSpecification(), pageable);
        model.addAttribute("page", page);
        model.addAttribute("pageable", pageable);
        model.addAttribute("modelSearch", userSearch);

        return "page/users/staffUserList";
    }

    @GetMapping("/create_view.do")
    public String createView(ModelMap model) {
        model.addAttribute("user", new StaffUser());
        return STAFF_USER_EDIT;
    }

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

        StaffUser found = staffUserService.findById(userId);
        model.addAttribute("user", found);
        return STAFF_USER_EDIT;
    }

    @PostMapping("/register.do")
    public String register(@ModelAttribute("user") UserRegisterDTO user,
                           BindingResult bindingResult,
                           ModelMap model) {

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

        validator.validate(user, bindingResult);

        if (bindingResult.hasErrors()) {
            model.addAttribute("user", user);
            return STAFF_USER_EDIT;
        }

        StaffUser newUser = staffUserMapper.map(user);
        staffUserService.create(newUser);
        return USERS_LIST_VIEW;
    }


    @PostMapping("/update.do")
    public String update(@RequestParam("esntlId") String esntlId,
                         @ModelAttribute("user") UserUpdateDTO user,
                         BindingResult bindingResult,
                         ModelMap model) {

        if (StringUtils.isEmpty(esntlId)) {
            return USERS_LIST_VIEW;
        }

        validator.validate(user, bindingResult);

        if (bindingResult.hasErrors()) {
            model.addAttribute("user", user);
            return STAFF_USER_EDIT;
        }

        StaffUser newUser = staffUserMapper.map(user);
        staffUserService.update(esntlId, newUser);
        return USERS_LIST_VIEW;
    }


    @PostMapping("/delete.do")
    public String delete(@ModelAttribute UserSearch modelSearch) {
        modelSearch.getCheckedIdForDel().forEach(id -> {
            if (!SecurityUtil.getCurrentUserEsntlId().equals(id)) { // 자기 자신은 삭제 불가
                staffUserService.deleteById(id);
            }
        });
        return USERS_LIST_VIEW;
    }

}
