package com.sunda.spmsuser.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.service.ISysLogService;
import com.sunda.spmsuser.entity.SpmsMdmUser;
import com.sunda.spmsuser.entity.SpmsUser;
import com.sunda.spmsuser.entity.SpmsUserRole;
import com.sunda.spmsuser.entity.SpmsUserWhs;
import com.sunda.spmsuser.entity.SpmsUserWorkshop;
import com.sunda.spmsuser.mapper.SpmsUserMapper;
import com.sunda.spmsuser.mapper.SpmsUserRoleMapper;
import com.sunda.spmsuser.mapper.SpmsUserWhsMapper;
import com.sunda.spmsuser.mapper.SpmsUserWorkshopMapper;
import com.sunda.spmsuser.service.ISpmsMdmUserService;
import com.sunda.spmsuser.service.ISpmsUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * SPMS用户信息表 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-01-25
 */
@Service
public class SpmsUserServiceImpl extends ServiceImpl<SpmsUserMapper, SpmsUser> implements ISpmsUserService {

    @Autowired
    SpmsUserMapper spmsUserMapper;

    @Autowired
    SpmsUserRoleMapper userRoleMapper;

    @Autowired
    SpmsUserWhsMapper userWhsMapper;

    @Autowired
    SpmsUserWorkshopMapper userWorkshopMapper;
    
    @Autowired
    ISysLogService iSysLogService;
    
    @Autowired
    private ISpmsMdmUserService iSpmsMdmUserService;

    @Override
    public SpmsUser getByUserId(String userId) {
        try {
            if (StringUtils.isEmpty(userId)){
                return null;
            }
            return spmsUserMapper.getByUserId(userId);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }


    @Override
    public SpmsUser getByUserEmail(String userId,String email) {
        try {
            if (StringUtils.isEmpty(userId)){
                throw new Exception("账号不能为空！The account cannot be empty!" );
            }
            if (StringUtils.isEmpty(email)){
                throw new Exception("邮箱不能为空！The email account cannot be empty!" );
            }
            return spmsUserMapper.getByUserEmail(userId,email);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public IPage<SpmsUser> spmsUserList(Page<SpmsUser> page) {
        try {
            return spmsUserMapper.selectPage(page, new QueryWrapper<>());
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public List<SpmsUser> getAllSpmsUserList() {
        return spmsUserMapper.selectList(null);
    }

    /**
     * {
     * 	"userInfo": {
     * 		"userId": "20001",
     * 		"loginPassword": "57697a33709a708ea59183af587593d2",
     * 		"workId": "20001",
     * 		"lastName": "20001",
     * 		"telephone": "13866668888",
     * 		"mobile": "13866668888",
     * 		"email": "sunda@sunda.com",
     * 		"positionId": "11",
     * 		"positionName": "position name",
     * 		"deptId": "123",
     * 		"deptName": "dept name",
     * 		"subcompanyId": "1234",
     * 		"subcompanyName": "subcompany id",
     * 		"company": "company",
     * 		"branchPoint": "12345",
     * 		"branchLine": "123456",
     * 		"managerId": "10000",
     * 		"managerName": "10000",
     * 		"oaStatus": "1",
     * 		"spmsStatus": "1"
     *        },
     * 	    "userRole": [{
     * 		    "uuid": "161556d97ae44139ad21659c5fb98e00",
     * 		    "roleId": "1001"
     *        }],
     * 	    "userWhs": [{
     * 		    "werks": "CN01",
     * 		    "whsLocationCode": "1061"
     *      }],
     * 	    "userWorkshop": [{
     * 		    "werks": "GH01",
     * 		    "workshopCode": "1002"
     *    }]
     * }
     * 新建用户，保存用户个人信息，及关联的角色、工厂、仓库、车间信息
     * @param doc
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseResult createSpmsUser(JSONObject doc, String MDPassword) {
        try {
            JSONObject userInfo = doc.getJSONObject("userInfo");
            String userId = userInfo.getString("userId");
            String spmsStatus = userInfo.getString("spmsStatus");
            // 创建或更新是所传的SPMS用户状态为spmsStatus=1正常时，需要判断用户在MDM是否可用，（OA用户信息也是从MDM获取的，所以这里直接获取MDM的信息）
            if ("1".equals(spmsStatus)) {
            	QueryWrapper<SpmsMdmUser> qw = new QueryWrapper<SpmsMdmUser>();
            	qw.eq("ALTER_EMPLID", userId);
            	SpmsMdmUser spmsMdmUser = iSpmsMdmUserService.getOne(qw);
            	// MDM员工状态：A-在职、I-离职
            	if (spmsMdmUser != null && "I".equals(spmsMdmUser.getHrStatus())) {
            		return ResponseResult.error("用户："+userId+" MDM状态为不可用，不能激活用户");
            	}
            }
            /** 创建用户个人信息，个人信息创建成功才能创建用户配置项信息 */
            int resp = createUser(userInfo, MDPassword);
            if (resp == 0){
                return ResponseResult.error("用户新增或更新失败");
            }

            /** 创建用户角色关系数据 */
            createUserRole(doc.getJSONArray("userRole"), userId);

            /** 创建用户-仓库关系数据 */
            createUserWhs(doc.getJSONArray("userWhs"), userId);

            /** 创建用户-车间关系数据 */
            createUserWorkshop(doc.getJSONArray("userWorkshop"), userId);

            return ResponseResult.success();
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error();
        }
    }

    int createUser(JSONObject userInfo, String MDPassword){
        SpmsUser spmsUser = new SpmsUser();
        spmsUser.setUserId(userInfo.getString("userId"));
        spmsUser.setWorkId(userInfo.getString("workId"));
        spmsUser.setLastName(userInfo.getString("lastName"));
        spmsUser.setTelephone(userInfo.getString("telephone"));
        spmsUser.setMobile(userInfo.getString("mobile"));
        spmsUser.setEmail(userInfo.getString("email"));
        spmsUser.setPositionId(userInfo.getString("positionId"));
        spmsUser.setPositionName(userInfo.getString("positionName"));
        spmsUser.setDeptId(userInfo.getString("deptId"));
        spmsUser.setDeptName(userInfo.getString("deptName"));
        spmsUser.setSubcompanyId(userInfo.getString("subcompanyId"));
        spmsUser.setSubcompanyName(userInfo.getString("subcompanyName"));
        spmsUser.setCompany(userInfo.getString("company"));
        spmsUser.setBranchPoint(userInfo.getString("branchPoint"));
        spmsUser.setBranchLine(userInfo.getString("branchLine"));
        spmsUser.setManagerId(userInfo.getString("managerId"));
        spmsUser.setManagerName(userInfo.getString("managerName"));
        spmsUser.setOaStatus(userInfo.getString("oaStatus"));
        spmsUser.setFactory(userInfo.get("factory")!=null?userInfo.getString("factory"):"");
        spmsUser.setSpmsStatus(userInfo.getString("spmsStatus"));
        if (spmsUserMapper.selectOne(new QueryWrapper<SpmsUser>().eq("WORK_CODE", spmsUser.getUserId())) != null){
            /** 对已存在用户则只执行用户更新操作，忽略 loginPassword-密码字段更新 */
            return spmsUserMapper.update(spmsUser, new QueryWrapper<SpmsUser>().eq("WORK_CODE", spmsUser.getUserId()));
        }
        /** 不存在的用户信息，则执行新建用户操作，此时给出默认的加密密码 */
        spmsUser.setLoginPassword(MDPassword);
        return spmsUserMapper.insert(spmsUser);
    }

    void createUserRole(JSONArray array, String userId){
        /** 创建用户-角色关系数据 */
        userRoleMapper.delete(new QueryWrapper<SpmsUserRole>().eq("WORK_CODE", userId));
        if (array.size() > 0){
        	List<SpmsUserRole> insertList = new ArrayList<>(array.size());
            for (int i = 0; i < array.size(); i ++){
                JSONObject doc = array.getJSONObject(i);
                SpmsUserRole userRole = new SpmsUserRole();
                userRole.setUuid(UUID.randomUUID().toString().replaceAll("-","").toLowerCase());
                userRole.setUserId(userId);
                //userRole.setRoleId(doc.getString("roleId"));
                userRole.setRoleUuid(doc.getString("uuid"));
                insertList.add(userRole);
            }
            // 根据角色ID去重
            ArrayList<SpmsUserRole> collect = insertList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SpmsUserRole::getRoleUuid))), ArrayList::new));
            for (SpmsUserRole whs : collect) {
            	userRoleMapper.insert(whs);
            }
        }
    }
    void createUserWhs(JSONArray array, String userId){
        /** 创建用户-仓库关系数据 */
        userWhsMapper.delete(new QueryWrapper<SpmsUserWhs>().eq("WORK_CODE", userId));
        if (array.size() > 0){
        	List<SpmsUserWhs> insertList = new ArrayList<>(array.size());
            for (int i = 0; i< array.size(); i++){
                JSONObject doc = array.getJSONObject(i);
                SpmsUserWhs userWhs = new SpmsUserWhs();
                userWhs.setUserId(userId);
                userWhs.setWerks(doc.getString("werks"));
                userWhs.setWhsLocationCode(doc.getString("whsLocationCode"));
                insertList.add(userWhs);
            }
            // 根据工厂、仓库去重
            ArrayList<SpmsUserWhs> collect = insertList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item ->item.getWerks()+"_"+item.getWhsLocationCode()))), ArrayList::new));
            for (SpmsUserWhs whs : collect) {
            	userWhsMapper.insert(whs);
            }
        }
    }
    void createUserWorkshop(JSONArray array, String userId){
        /** 创建用户-车间关系数据 */
        userWorkshopMapper.delete(new QueryWrapper<SpmsUserWorkshop>().eq("WORK_CODE", userId));
        if (array.size() > 0) {
        	List<SpmsUserWorkshop> insertList = new ArrayList<>(array.size());
            for (int i = 0; i< array.size(); i++) {
                JSONObject doc = array.getJSONObject(i);
                SpmsUserWorkshop userWorkshop = new SpmsUserWorkshop();
                userWorkshop.setUserId(userId);
                userWorkshop.setWerks(doc.getString("werks"));
                userWorkshop.setWorkshopCode(doc.getString("workshopCode"));
                insertList.add(userWorkshop);
            }
            // 根据工厂、车间去重
            ArrayList<SpmsUserWorkshop> collect = insertList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item ->item.getWerks()+"_"+item.getWorkshopCode()))), ArrayList::new));
            for (SpmsUserWorkshop whs : collect) {
            	userWorkshopMapper.insert(whs);
            }
        }
    }

    /** 更新用户登录密码 */
    @Override
    public ResponseResult updatePassword(String userId, String MDPassword) {
        if (userId == null || userId.length() == 0 || MDPassword.length() == 0){
            return ResponseResult.error("请求参数错误");
        }
        if (spmsUserMapper.updatePassword(userId, MDPassword) > 0){
            return ResponseResult.success();
        }
        return ResponseResult.error();
    }

    @Override
    public void oaCreateSpmsUser(Map<String, Object> map, String MDPassword) {
        SpmsUser spmsUser = new SpmsUser();
        spmsUser.setUserId(map.get("userId").toString());
        spmsUser.setWorkId(map.get("workId").toString());
        spmsUser.setLastName(map.get("lastName").toString());
        spmsUser.setTelephone(map.get("telephone").toString());
        spmsUser.setMobile(map.get("mobile").toString());
        spmsUser.setEmail(map.get("email").toString());
        spmsUser.setPositionId(map.get("positionId").toString());
        spmsUser.setPositionName(map.get("positionName").toString());
        spmsUser.setDeptId(map.get("deptId").toString());
        spmsUser.setDeptName(map.get("deptName").toString());
        spmsUser.setSubcompanyId(map.get("subcompanyId").toString());
        spmsUser.setSubcompanyName(map.get("subcompanyName").toString());
        spmsUser.setCompany(map.get("company").toString());
        spmsUser.setBranchPoint(map.get("branchPoint").toString());
        spmsUser.setBranchLine(map.get("branchLine").toString());
        spmsUser.setManagerId(map.get("managerId").toString());
        spmsUser.setManagerName(map.get("managerName").toString());
        spmsUser.setOaStatus(map.get("oaStatus").toString());
        spmsUser.setLoginPassword(MDPassword);
        spmsUser.setSpmsStatus("1");
        this.baseMapper.insert(spmsUser);
    }

    @Override
    public ResponseResult updateSpmsUserInfo(Map<String, Object> map) {
        if (null == map || map.size() == 0){
            return ResponseResult.error("请求参数不能为空");
        }
        QueryWrapper<SpmsUser> queryWrapper = new QueryWrapper<SpmsUser>().eq("WORK_CODE", map.get("userId").toString());
        SpmsUser spmsUser = new SpmsUser();
        spmsUser.setWorkId(map.get("workId").toString());
        spmsUser.setLastName(map.get("lastName").toString());
        spmsUser.setTelephone(map.get("telephone").toString());
        spmsUser.setMobile(map.get("mobile").toString());
        spmsUser.setEmail(map.get("email").toString());
        spmsUser.setPositionId(map.get("positionId").toString());
        spmsUser.setPositionName(map.get("positionName").toString());
        spmsUser.setDeptId(map.get("deptId").toString());
        spmsUser.setDeptName(map.get("deptName").toString());
        spmsUser.setSubcompanyId(map.get("subcompanyId").toString());
        spmsUser.setSubcompanyName(map.get("subcompanyName").toString());
        spmsUser.setCompany(map.get("company").toString());
        spmsUser.setBranchPoint(map.get("branchPoint").toString());
        spmsUser.setBranchLine(map.get("branchLine").toString());
        spmsUser.setManagerId(map.get("managerId").toString());
        spmsUser.setManagerName(map.get("managerName").toString());
        spmsUser.setOaStatus(map.get("oaStatus").toString());
        int resp = this.baseMapper.update(spmsUser, queryWrapper);
        if (resp <= 0){
            return ResponseResult.error("更新失败");
        }
        return ResponseResult.success().add("spmsUser", this.baseMapper.selectOne(queryWrapper));
    }
    
    /**
     * 新增系统用户
     */
    @Transactional(rollbackFor = Exception.class)
	@Override
	public ResponseResult createSystemUser(JSONObject doc, String MDPassword, String operationUserId) {
    	try {
            JSONObject userInfo = doc.getJSONObject("userInfo");
            SpmsUser spmsUser = new SpmsUser();
            spmsUser.setUserId(userInfo.getString("userId"));
            spmsUser.setLastName(userInfo.getString("lastName"));
            spmsUser.setPositionName(userInfo.getString("positionName"));
            spmsUser.setDeptName(userInfo.getString("deptName"));
            spmsUser.setSpmsStatus(userInfo.getString("spmsStatus"));
            spmsUser.setLoginPassword(MDPassword);
            if (spmsUserMapper.selectOne(new QueryWrapper<SpmsUser>().eq("WORK_CODE", spmsUser.getUserId())) != null){
                return ResponseResult.error("用户ID："+userInfo.getString("userId")+"已存在");
            }
            spmsUserMapper.insert(spmsUser);
            // 操作日志
            iSysLogService.addSysLog("1","用户注册","注册", operationUserId,"","createSpmsUser","/spmsUser/createSpmsUser","POST","",userInfo.toString(),"","");
            return ResponseResult.success();
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error();
        }
	}

    @Transactional(rollbackFor = Exception.class)
	@Override
	public ResponseResult saveSpmsUser(JSONObject doc, String mDPassword) throws Exception {
		// 创建用户个人信息，个人信息创建成功才能创建用户配置项信息
    	JSONObject userInfo = doc.getJSONObject("userInfo");
    	String userId = userInfo.getString("userId");
        int resp = createUser(userInfo, mDPassword);
        if (resp == 0){
            return ResponseResult.error("用户新增或更新失败");
        }
        // 创建用户角色关系数据
        createUserRole(doc.getJSONArray("userRole"), userId);
        // 创建用户-仓库关系数据
        createUserWhs(doc.getJSONArray("userWhs"), userId);
        // 创建用户-车间关系数据
        createUserWorkshop(doc.getJSONArray("userWorkshop"), userId);
        return ResponseResult.success();
	}


	@SuppressWarnings("unchecked")
	@Override
	public IPage getUserListByParam(JSONObject doc) {
		IPage page = new Page<>(doc.getInteger("pageNo"),doc.getInteger("pageSize"));
		SpmsUser user = new SpmsUser();
		user.setUserId(doc.get("userId") != null ? doc.getString("userId") : "");
		user.setCompany(doc.get("company") != null ? doc.getString("company") : "");
		user.setLastName(doc.get("lastName") != null ? doc.getString("lastName") : "");
		user.setSubcompanyName(doc.get("subcompanyName") != null ? doc.getString("subcompanyName") : "");
		user.setDeptName(doc.get("deptName") != null ? doc.getString("deptName") : "");
		user.setSpmsStatus(doc.get("spmsStatus") != null ? doc.getString("spmsStatus") : "");
		user.setPositionName(doc.get("positionName") != null ? doc.getString("positionName") : "");
		List<Map<String, Object>> mapList = this.baseMapper.selectUserListByPage(page, user);
		page.setRecords(mapList);
        return page;
	}


	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> getMdmUserInfo(String userId) {
		QueryWrapper<SpmsMdmUser> qw = new QueryWrapper<SpmsMdmUser>();
    	qw.eq("ALTER_EMPLID", userId);
    	SpmsMdmUser spmsMdmUser = iSpmsMdmUserService.getOne(qw);
    	Map<String, Object> map = new HashMap<>();
    	if (spmsMdmUser == null) {
    		return null;
    	}
    	// 工号
    	map.put("userId", spmsMdmUser.getAlterEmplid());
        map.put("workId", "");
        // 名称
        String middleName = StringUtils.isNotEmpty(spmsMdmUser.getMiddleName()) ? spmsMdmUser.getMiddleName() : "";
        map.put("lastName", spmsMdmUser.getLastName()+middleName+spmsMdmUser.getFirstName());
        // 手机号
        map.put("telephone", spmsMdmUser.getPhone());
        map.put("mobile", "");
        // 邮箱
        map.put("email", spmsMdmUser.getEmailAddr());
        // 岗位ID
        map.put("positionId", spmsMdmUser.getPositionNbr());
        // 岗位名称
        map.put("positionName", spmsMdmUser.getPositionNbrDescr());
        // 部门ID
        map.put("deptId", spmsMdmUser.getDeptid());
        // 分部ID
        map.put("subcompanyId", "");
        // 分部名称
        map.put("subcompanyName", "");
        if (StringUtils.isNotEmpty(spmsMdmUser.getSupervisorId())) {
        	QueryWrapper<SpmsMdmUser> mdmQw = new QueryWrapper<SpmsMdmUser>();
        	mdmQw.eq("EMPLID", userId);
        	SpmsMdmUser emplUser = iSpmsMdmUserService.getOne(mdmQw);
        	// 直接上级id
        	map.put("managerId", spmsMdmUser.getSupervisorId());
        	if (emplUser != null) {
        		String middleName22 = StringUtils.isNotEmpty(emplUser.getMiddleName()) ? emplUser.getMiddleName() : "";
        		// 直接上级名称
        		map.put("managerName", emplUser.getLastName()+middleName22+emplUser.getFirstName());
        	} else {
        		map.put("managerName", "");
        	}
        } else {
        	map.put("managerId", "");
        	map.put("managerName", "");
        }
        if (StringUtils.isNotEmpty(spmsMdmUser.getAttrs())) {
        	JSONObject obj = JSONObject.parseObject(spmsMdmUser.getAttrs());
        	// 岗位名称
        	JSONArray positionArray = obj.getJSONArray("POSITION_NBR");
        	for (int i = 0; i < positionArray.size(); i++) {
        		Map<String, Object> posMap = (Map<String, Object>) positionArray.get(i);
        		if ("ZH".equals(posMap.get("LANG").toString())) {
        			map.put("positionName", posMap.get("VALUE").toString());
        			break;
        		}
        	}
        	// 部门名称
        	JSONArray depatArray = obj.getJSONArray("DEPTID");
        	for (int i = 0; i < depatArray.size(); i++) {
        		Map<String, Object> daprtMap = (Map<String, Object>) depatArray.get(i);
        		if ("ZH".equals(daprtMap.get("LANG").toString())) {
        			map.put("deptName", daprtMap.get("VALUE").toString());
        			break;
        		}
        	}
            // 分公司名称
        	JSONArray countryArray = obj.getJSONArray("COUNTRY");
        	for (int i = 0; i < countryArray.size(); i++) {
        		Map<String, Object> countryMap = (Map<String, Object>) countryArray.get(i);
        		if ("ZH".equals(countryMap.get("LANG").toString())) {
        			map.put("company", countryMap.get("VALUE").toString());
        			break;
        		}
        	}
            // 分点名称
        	JSONArray locationArray = obj.getJSONArray("LOCATION");
        	for (int i = 0; i < locationArray.size(); i++) {
        		Map<String, Object> locationMap = (Map<String, Object>) locationArray.get(i);
        		if ("ZH".equals(locationMap.get("LANG").toString())) {
        			map.put("branchPoint", locationMap.get("VALUE").toString());
        			break;
        		}
        	}
        	// 分线名称
        	JSONArray lineArray = obj.getJSONArray("DC_POSN_BRACNG");
        	for (int i = 0; i < lineArray.size(); i++) {
        		Map<String, Object> lineMap = (Map<String, Object>) lineArray.get(i);
        		if ("ZH".equals(lineMap.get("LANG").toString())) {
        			map.put("branchLine", lineMap.get("VALUE").toString());
        			break;
        		}
        	}
        }
        map.put("oaStatus", "A".equals(spmsMdmUser.getHrStatus()) ? "1" : "4");
        return map;
	}
}
