package com.infoepoch.pms.dispatchassistant.controller.basic;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.infoepoch.pms.dispatchassistant.common.component.BaseController;
import com.infoepoch.pms.dispatchassistant.common.component.Result;
import com.infoepoch.pms.dispatchassistant.common.constant.ErrorCodes;
import com.infoepoch.pms.dispatchassistant.common.exception.NotLoginException;
import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import com.infoepoch.pms.dispatchassistant.common.utils.JsonNodeUtils;
import com.infoepoch.pms.dispatchassistant.common.utils.JsonUtils;
import com.infoepoch.pms.dispatchassistant.domain.basic.menu.Menu;
import com.infoepoch.pms.dispatchassistant.domain.basic.organization.Organization;
import com.infoepoch.pms.dispatchassistant.domain.basic.organization.OrganizationRoot;
import com.infoepoch.pms.dispatchassistant.domain.basic.role.Role;
import com.infoepoch.pms.dispatchassistant.domain.basic.role.RoleCriteria;
import com.infoepoch.pms.dispatchassistant.domain.basic.role.RoleFileService;
import com.infoepoch.pms.dispatchassistant.domain.basic.role.RoleService;
import com.infoepoch.pms.dispatchassistant.domain.basic.user.User;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/role")
public class RoleController extends BaseController {

    private final static Logger logger = LoggerFactory.getLogger(RoleController.class);

    @Autowired
    private Auth auth;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RoleFileService roleFileService;


    @Autowired
    private ObjectMapper objectMapper;

    @GetMapping("/init")
    public Result init() {
        Map<String, Object> resultMap = new HashMap<>();

        List<Organization> organizationList = OrganizationRoot.getRootOrganizations();
        resultMap.put("organizationList", OrganizationRoot.changeToOrgTreeList(organizationList));

        return Result.successData(resultMap);
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public Result findList(@RequestParam(value = "name", required = false) String name,
                           @RequestParam(value = "page_index", defaultValue = "1") int pageIndex,
                           @RequestParam(value = "page_size", defaultValue = "10") int pageSize) throws NotLoginException {
        RoleCriteria criteria = new RoleCriteria();
        User user = auth.getUserReq();
        if (OrganizationRoot.judgeBranchCompany(user.getOrganizationId())) {
            criteria.setBranchFlag(true);
        }
        criteria.setPageIndex(pageIndex);
        criteria.setPageSize(pageSize);
        if (StringUtils.isNotBlank(name)) {
            criteria.setName(name);
        }
        List<Role> roles = roleService.queryByPage(criteria);
        int totalCount = roleService.queryByPageCount(criteria);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("list", roles);
        resultMap.put("totalCount", totalCount);
        return Result.successData(resultMap);
    }

    /**
     * 根据id删除角色
     *
     * @param id 角色id
     * @return
     */
    @RequestMapping(value = "/remove", method = RequestMethod.POST)
    public Result removeById(@RequestParam("id") String id) {
        try {
            roleService.removeRole(id);
            return Result.success();
        } catch (Exception e) {
            logger.info("remove role error:", e);
            return Result.error(ErrorCodes.DEFAULT, e.getMessage());
        }
    }

    /**
     * 新增角色
     *
     * @param jsonStr
     * @return
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public Result create(@RequestBody String jsonStr) {
        Role role = JsonUtils.jsonToObject(jsonStr, Role.class);
        try {
            roleService.createRole(role.getName(), role.getDescription(), role.isDisabled());
        } catch (Exception e) {
            logger.info("创建角色失败：", e);
            return Result.error(ErrorCodes.DEFAULT, "创建角色失败！");
        }
        return Result.success();
    }

    /**
     * 修改角色信息
     *
     * @param jsonStr
     * @return
     */
    @RequestMapping(value = "/modify", method = RequestMethod.POST)
    public Result modify(@RequestBody String jsonStr) {
        Role role = JsonUtils.jsonToObject(jsonStr, Role.class);
        roleService.modifyRole(role.getId(), role.getName(), role.getDescription(), role.isDisabled());
        return Result.success();
    }

    /**
     * 关联用户
     *
     * @param id      角色id
     * @param userIds 用户id集合
     * @return
     */
    @RequestMapping(value = "/relate-user", method = RequestMethod.POST)
    public Result relateUser(@RequestParam("id") String id, @RequestParam(value = "data[]", required = false) List<String> userIds) throws NotLoginException {
        User user = auth.getUserReq();
        try {
            if (OrganizationRoot.judgeBranchCompany(user.getOrganizationId())) {
                Organization department = OrganizationRoot.getCompanyById(user.getOrganizationId());
                roleService.relateUsers(department.getId(), id, userIds);
            } else {
                roleService.relateUsers(id, userIds);
            }
            return Result.success();
        } catch (Exception e) {
            logger.info("relate user error:", e);
            return Result.error(ErrorCodes.DEFAULT, e.getMessage());
        }
    }

    /**
     * 获取角色关联的用户
     *
     * @param id 角色id
     * @return
     */
    @RequestMapping(value = "/relate-user-list", method = RequestMethod.GET)
    public Map relateUserList(@RequestParam("id") String id) {
        String parentOrgId = "5262";//根组织
        User user = auth.getUser();
        Organization department = OrganizationRoot.getCompanyById(user.getOrganizationId());
        if (department != null && OrganizationRoot.judgeBranchCompany(department.getId())) {
            parentOrgId = department.getId();
        }
        //查询已选用户
        List<User> selectedUsers = roleService.querySelectedUserList(id, parentOrgId);
        //获取所有用户，过滤已经选择的用户
        List<User> resultUser = roleService.queryNotSelectedUserList(id, parentOrgId);
        List<User> userAllList = new ArrayList<>();
        userAllList.addAll(resultUser);
        userAllList.addAll(selectedUsers);
        Map<String, Object> map = Result.successData(setUserListOrganization(resultUser)).toMap();
        map.put("selectedUsers", setUserListOrganization(selectedUsers));
        List<Organization> organizationList = OrganizationRoot.getByIds(userAllList.stream().map(User::getOrganizationId).collect(Collectors.toList()));
        map.put("organizationList", organizationList);
        return map;
    }

    private List<User> setUserListOrganization(List<User> userList) {
        List<Organization> organizationList = OrganizationRoot.getByIds(userList.stream().map(User::getOrganizationId).collect(Collectors.toList()));

        Map<String, Organization> organizationMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(organizationList)) {
            organizationList.forEach(organization -> organizationMap.put(organization.getId(), organization));
        }
        List<User> resultList = userList.stream().peek(user -> user.setOrganizationName(organizationMap.get(user.getOrganizationId()) != null ? organizationMap.get(user.getOrganizationId()).getName() : "")).collect(Collectors.toList());
//        Collator collator = Collator.getInstance();
//        resultList.sort((o1, o2) -> collator.compare(o1.getPosition(), o2.getPosition()));
        return resultList;
    }

    @RequestMapping(value = "/query-users", method = RequestMethod.POST)
    public Result queryUsers(@RequestParam(value = "fullname", required = false) String fullname, @RequestParam(value = "departmentId", required = false) String departmentId,
                             @RequestParam(value = "selectedUsers", required = false) String selectedUsersJsonStr, @RequestParam(value = "roleId", required = false) String roleId) {
        List<User> queryUser = new ArrayList<>();
        // 搜索结果去除已选中的 ..
        List<User> selectedUserList = JsonUtils.jsonToList(selectedUsersJsonStr, User.class);
        List<String> selectedUserIds = null;
        if (CollectionUtils.isNotEmpty(selectedUserList)) {
            selectedUserIds = selectedUserList.stream().map(s -> s.getId()).collect(Collectors.toList());
        }

        if (StringUtils.isBlank(departmentId)) {
            departmentId = "5262";//根组织
        }
        List<User> userList = new ArrayList<>();
        if (StringUtils.isNotBlank(fullname)) {
            userList = roleService.queryNotSelectedUserList(roleId, departmentId, fullname);
        } else {
            userList = roleService.queryNotSelectedUserList(roleId, departmentId);
        }

        if (CollectionUtils.isNotEmpty(selectedUserIds)) {
            List<String> finalSelectedUserIds = selectedUserIds;
            queryUser = userList.stream().filter(f -> !finalSelectedUserIds.contains(f.getId())).collect(Collectors.toList());
        } else {
            queryUser = userList;
        }
        return Result.successData(setUserListOrganization(queryUser));
    }

    /**
     * 关联菜单
     *
     * @return
     */
    @RequestMapping(value = "/relate-menu", method = RequestMethod.POST)
    public Result relateMenu(@RequestBody String str) throws IOException {
        try {
            JsonNode jnode = objectMapper.readTree(str);
            String id = JsonNodeUtils.toString(jnode.get("id"));
            JsonNode dataList = jnode.get("data");
            List<String> menuIds = new ArrayList<>();
            List<String> invoiceList = new ArrayList<>();
            for (JsonNode item : dataList) {
                menuIds.add(JsonNodeUtils.toString(item.get("id")));
                String invoice = JsonNodeUtils.toString(item.get("invoice"));
                invoiceList.add("".equals(invoice) ? "1" : invoice);
            }
            roleService.relateMenus(id, menuIds, invoiceList);
            return Result.success();
        } catch (Exception e) {
            logger.info("relate menu error:", e);
            return Result.error(ErrorCodes.DEFAULT, e.getMessage());
        }
    }

    /**
     * 根据角色id获取关联的菜单
     *
     * @param id 角色id
     * @return
     */
    @RequestMapping(value = "/relate-menu-list", method = RequestMethod.GET)
    public Result relateMenuList(@RequestParam("id") String id) {
        List<Menu> menus;
        try {
            menus = roleService.queryRelateMenus(id, Menu.TYPE_MENU_MAIN);
        } catch (Exception e) {
            return Result.error(ErrorCodes.DEFAULT, e.getMessage());
        }
        return Result.successData(menus);
    }

    /**
     * 获取当前登录人角色列表字符串
     *
     * @return
     * @throws NotLoginException
     */
    @GetMapping(value = "/current-user-role-list")
    public Result currentUserRoleList() throws NotLoginException {
        User user = auth.getUserReq();
        List<Role> roleList = roleService.queryByUserId(user.getId());
        String roleStr = StringUtils.join(roleList.stream().filter(role -> !role.isDisabled()).map(Role::getName).collect(Collectors.toList()), ",");
        return Result.successData(roleStr);
    }

    /**
     * @param roleId
     * @param request
     * @param response
     */
    @PostMapping("/relate-user-export")
    public void relateUserExport(String roleId, String departmentId, HttpServletRequest request, HttpServletResponse response) throws NotLoginException {
        User user = auth.getUserReq();
        if (OrganizationRoot.judgeBranchCompany(user.getOrganizationId())) {
            departmentId = OrganizationRoot.getCompanyById(user.getOrganizationId()).getId();
        }
        roleFileService.roleExport(roleId, departmentId, request, response);
    }

    /**
     * 根据角色名称获取部门用户列表
     *
     * @param departmentId
     * @param roleName
     * @return
     */
    @PostMapping("/department-user-list")
    public Result departmentUserList(@RequestParam(required = false) String departmentId, @RequestParam(required = false) String roleName) {
        if (StringUtils.isBlank(departmentId)) {
            throw new ValidationException("部门id不能为空");
        }
        if (StringUtils.isBlank(roleName)) {
            throw new ValidationException("角色名称不能为空");
        }
        Organization department = OrganizationRoot.getDepartmentById(departmentId);
        List<User> userList = roleService.queryUsersByRoleName(roleName, department.getId());
        if (userList == null)
            userList = new ArrayList<>();
        return Result.successData(userList);
    }

    /**
     * @return
     */
    @PostMapping("/copy-relate-user")
    public Result copyRelateUser(@RequestBody Map<String, String> map) {
        String roleId = map.get("roleId");
        String copyRoleId = map.get("copyRoleId");
        roleService.copyRelateUser(roleId, copyRoleId);
        return Result.success();
    }

}
