package cn.com.countrygarden.bi.main.controller;

import cn.com.countrygarden.bi.main.core.Response;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.AccessToken;
import cn.com.countrygarden.bi.main.model.LuosimaoVerifyConst;
import cn.com.countrygarden.bi.main.model.LuosimaoVerifyResponse;
import cn.com.countrygarden.bi.main.model.PageData;
import cn.com.countrygarden.bi.main.model.sys.Function;
import cn.com.countrygarden.bi.main.model.sys.Menu;
import cn.com.countrygarden.bi.main.model.sys.Role;
import cn.com.countrygarden.bi.main.model.sys.UserRoles;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysDepartment;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysUser;
import cn.com.countrygarden.bi.main.service.*;
import cn.com.countrygarden.bi.main.service.twerp.hm.TbSysUserService;
import com.github.pagehelper.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;


@Controller("UserController")
@RequestMapping("/api/user")
public class UserController {
    @Autowired
    private TbSysUserService tbSysUserService;

    @Autowired
    private AccessTokenService accessTokenService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserFunctionService userFunctionService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    @Qualifier("applicationProperties")
    private Properties applicationProperties;

    @Autowired
    private RoleService roleService;

    @RequestMapping(value = "/login", method = RequestMethod.POST, produces = "application/json;charset=utf-8")
    public @ResponseBody
    Object login(@RequestParam(value = "LoginCode", required = true) String loginCode,
                 @RequestParam(value = "PassWord", required = true) String password,
                 @RequestParam(value = "response", required = true) String luosimaoResponse) {
        if(!DataVUser.RESPONSE_CODE.equals(luosimaoResponse)){
            String verifyApiKey = applicationProperties.getProperty("luosimao.verify.api_key");
            String verifyUrl = applicationProperties.getProperty("luosimao.verify.url");
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
            params.add("api_key", verifyApiKey);
            params.add("response", luosimaoResponse);
            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
            try{
                LuosimaoVerifyResponse verifyResponse = restTemplate.postForObject(verifyUrl,requestEntity, LuosimaoVerifyResponse.class);
                if(!LuosimaoVerifyConst.SUCCESS.equals(verifyResponse.getRes())){
                    throw new ServiceException("验证码错误,请重试");
                }
            } catch (RestClientException ex){
                throw new ServiceException("验证码服务异常,请稍后再试");
            }
        }

        Map<String, Object> user = tbSysUserService.login(loginCode, password);
        String userCode = (String) user.get("UserCode");
        List<Role> roles = userRoleService.findUserRoles(userCode);
        List<Menu> menus = menuService.findByUserCode(userCode);
        if(menus.size()==0){
            throw new ServiceException("权限不足，请先发起流程申请开通权限或联系管理员");
        }
        List<Function> functions = userFunctionService.findUserFunctions(userCode);
        user.put("sysMenus",menus);
        user.put("userFunctions",functions);
        return Response.response(user);
    }


    @RequestMapping(value = "/logout", method = RequestMethod.POST, produces = "application/json;charset=utf-8")
    public @ResponseBody
    Object logout() {
        tbSysUserService.logout();
        return Response.response();
    }

    @RequestMapping(value = "/menus", method = {RequestMethod.GET , RequestMethod.POST}, produces = "application/json;charset=utf-8")
    public @ResponseBody Object getUserMenus(HttpServletRequest request, HttpServletResponse response){
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        List<Menu> menus = menuService.findByUserCode(token.getUserCode());
        return Response.response(menus);
    }


    @RequestMapping(value = "/roles", method = {RequestMethod.GET , RequestMethod.POST}, produces = "application/json;charset=utf-8")
    public @ResponseBody Object getUserRoles(HttpServletRequest request, HttpServletResponse response){
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        List<Role> roles = userRoleService.findUserRoles(token.getUserCode());
        return Response.response(roles);
    }

    @RequestMapping(value = "/functions", method = {RequestMethod.GET , RequestMethod.POST}, produces = "application/json;charset=utf-8")
    public @ResponseBody Object getUserFunctions(HttpServletRequest request, HttpServletResponse response){
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        List<Function> functions = userFunctionService.findUserFunctions(token.getUserCode());
        return Response.response(functions);
    }

    @RequestMapping(value = "/departments", method = {RequestMethod.GET , RequestMethod.POST}, produces = "application/json;charset=utf-8")
    public @ResponseBody Object getDepartments(){
        List<TbSysDepartment> result = tbSysUserService.listDepartments();
        return Response.response(result);
    }

    @RequestMapping(value = "/search", method =RequestMethod.GET, produces = "application/json;charset=utf-8")
    public @ResponseBody Object getUsers(@RequestParam(value = "search",required = false) String searchKey,
                                         @RequestParam(value = "roleCode",required = false,defaultValue = "") String roleCode,
                                         @RequestParam(value = "page",required=false, defaultValue = "1") int page,
                                         @RequestParam(value = "size",required=false, defaultValue = "10") int size){
        if(!StringUtils.isEmpty(roleCode)){
            if(StringUtils.isEmpty(searchKey)){
                // 去除ERP人员为删除状态, 但是在DUP已经被赋予过权限的人员
                List<String> userCodesOfDisable = filterUserCodeOfDisable(roleCode);

                Page<UserRoles> rolePage = userRoleService.searchByRoleCode(roleCode,page,size, userCodesOfDisable);
                PageData pageData = new PageData(rolePage);
                List<String> userCodes = new ArrayList<String>();
                for(UserRoles role : rolePage){
                    userCodes.add(role.getUserCode());
                }
                List<TbSysUser> users= tbSysUserService.findByUserCodes(userCodes);
                for(TbSysUser user:users){
                    user.setHasRole(true);
                }
                pageData.setData(users);
                return Response.response(pageData);
            } else {
                PageData result = tbSysUserService.findByDepartmentOrKey(null,searchKey,page,size);

                if(result.getData()!=null){
                    List<TbSysUser> userList = (List<TbSysUser>)result.getData();
                    if(userList.size()>0){
                        List<String> userCodes = new ArrayList<String>();
                        for(TbSysUser user:userList){
                            userCodes.add(user.getUserCode());
                        }
                        List<UserRoles> roleUsers = userRoleService.searchByUserCodes(roleCode,userCodes);
                        Map<String,String> roleUsersMap = new HashMap<String,String>();
                        for(UserRoles user: roleUsers){
                            roleUsersMap.put(user.getUserCode(),user.getUserCode());
                        }
                        for(TbSysUser user: userList){
                            if(roleUsersMap.get(user.getUserCode())!=null){
                                user.setHasRole(true);
                            } else {
                                user.setHasRole(false);
                            }
                        }
                    }
                }
                return Response.response(result);
            }

        } else {
            PageData result = tbSysUserService.findByDepartmentOrKey(null,searchKey,page,size);
            return Response.response(result);
        }

    }
    /**
     * 过滤无效的用户
     * @param roleCode
     * @return java.util.List<java.lang.String>
     */
    private List<String> filterUserCodeOfDisable(String roleCode) {
        List<String> userCodesOfAll = userRoleService.selectUserCodes(roleCode);
        if (userCodesOfAll != null && userCodesOfAll.size() > 0) {
            List<String> userCodesOfEnable = tbSysUserService.findByUserCodesOfEnable(userCodesOfAll);
            if (userCodesOfEnable != null && userCodesOfEnable.size() > 0) {
                userCodesOfAll.removeAll(userCodesOfEnable);
            } else {
                userCodesOfAll = Collections.EMPTY_LIST;
            }

        }
        return userCodesOfAll;
    }

    @RequestMapping(value = "/role/user", method =RequestMethod.PUT, produces = "application/json;charset=utf-8")
    public @ResponseBody Object addRoleUsers(@RequestParam(value="userCode",required = false) String userCode,
                                         @RequestParam(value = "roleCode") String roleCode,
                                         HttpServletRequest request, HttpServletResponse response){
        if(StringUtils.isEmpty(userCode)){
            throw new ServiceException("没有选中ERP账号，请选择ERP账号");
        }
        if(StringUtils.isEmpty(roleCode)){
            throw new ServiceException("没有选中角色，请选择角色");
        }
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        roleService.checkIsAdmin(token.getUserCode());
        userRoleService.addUserToRole(token.getUserCode(),userCode,roleCode);
        return Response.response("");
    }

    @RequestMapping(value = "/role/user", method =RequestMethod.DELETE, produces = "application/json;charset=utf-8")
    public @ResponseBody Object deleteRoleUsers(@RequestParam(value="userCode",required = false) String userCode,
                                                @RequestParam(value = "roleCode") String roleCode,
                                                HttpServletRequest request, HttpServletResponse response){
        if(StringUtils.isEmpty(userCode)){
            throw new ServiceException("没有选中ERP账号，请选择ERP账号");
        }
        if(StringUtils.isEmpty(roleCode)){
            throw new ServiceException("没有选中角色，请选择角色");
        }
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        roleService.checkIsAdmin(token.getUserCode());
        userRoleService.deleteUserRoles(userCode,roleCode,token.getUserCode());
        return Response.response("");
    }

    @RequestMapping(value = "/role/all", method =RequestMethod.GET, produces = "application/json;charset=utf-8")
    public @ResponseBody Object deleteRoleUsers(
                                                HttpServletRequest request, HttpServletResponse response){
        List<Role> roles = userRoleService.listRoles();
        return Response.response(roles);
    }

}
