package com.yifu.cloud.plus.v1.yifu.archives.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.yifu.cloud.plus.v1.business.entity.system.TBusDept;
import com.yifu.cloud.plus.v1.business.entity.system.TBusLable;
import com.yifu.cloud.plus.v1.business.vo.system.BusDeptVo;
import com.yifu.cloud.plus.v1.business.vo.system.BusLableVo;
import com.yifu.cloud.plus.v1.business.vo.vacation.UpdateVacationRedundancyDTO;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TBusinessEmployeeExtendInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeProject;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TBusinessEmployeeExtendInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.TBusinessEmployeeExtendInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprBusinessProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @description: b端员工信息拓展信息 service实现
 * @author: wangweiguo
 * @date: 2021/8/6
 */
@Service
@AllArgsConstructor
@EnableConfigurationProperties(DaprBusinessProperties.class)
public class TBusinessEmployeeExtendInfoServiceImpl extends ServiceImpl<TBusinessEmployeeExtendInfoMapper, TBusinessEmployeeExtendInfo>
implements TBusinessEmployeeExtendInfoService {

	private final ObjectMapper objectMapper;

	private final DaprBusinessProperties daprBusinessProperties;

	public static final String TAG_IS_BANED =  "标签被禁用";

	public static final String TAG_IS_NOT_EXIST =  "标签不存在";

	public static final String TELECOMNUMBER_IS_EXIST =  "电信工号已存在";

	public static final String EMPLOYEE_TAGS_EXCEED =  "人员标签不能超过10个";

	public static final String DEPT_NAME_IS_NOT_EXIST =  "部门名称不存在";

	public static final String JSON_DATE_RESOLVER_ERROR =  "入职时间，请使用正确的日期格式，如：XXXX-XX-XX，";

	public static final String JSON_RESOLVER_ERROR =  "批量导入更新人员信息json数据格式解析失败";

	public static final String DEPT_LIST_IS_NULL =  "部门列表为空";

	public static final String LABEL_LIST_IS_NULL =  "标签列表为空";

	public static final String BATCH_USER_EXTEND_DATA_ERROR =  "批量更新人员附表信息数据失败";

	public static final String ID_CARD_IS_NOT_EXIST =  "Hro系统中身份证号不存在,或者没有该人员的结算主体权限";

    /**
     * 更新人员信息冗余字段
     * @description: 更新人员信息冗余字段
     * @param dtoList
     * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.List<ErrorMessage>>
     * @author: wangweiguo
     * @date: 2021/8/12
     */
    @Override
    public Boolean updateEmployeeExtendRedundancy(List<UpdateEmployeeExtendRedundancyDTO> dtoList) {
		if (CollUtil.isEmpty(dtoList)) {
			return false;
		}
		for (UpdateEmployeeExtendRedundancyDTO v : dtoList) {
			// 根据部门id更新冗余的部门信息
			if (null != v.getDepartId()) {
				this.lambdaUpdate()
						.eq(TBusinessEmployeeExtendInfo::getDepartId, v.getDepartId())
						.set(TBusinessEmployeeExtendInfo::getDepartName, v.getDepartName())
						.set(TBusinessEmployeeExtendInfo::getDepartCode, v.getTreeLogo())
						.set(TBusinessEmployeeExtendInfo::getDepartId, v.getDepartIdVal())
						.update();
			} else {
				if (StringUtils.isBlank(v.getEmpIdcard())) {
					continue;
				}
				v.setEmployeeTags(formatLabelId(v.getEmployeeTags()));
				// 身份证号更新冗余的离职，标签，证件相关信息
				this.lambdaUpdate()
						.eq(TBusinessEmployeeExtendInfo::getEmpIdcard, v.getEmpIdcard())
						.set(null != v.getEmployeeTags(), TBusinessEmployeeExtendInfo::getEmployeeTags, v.getEmployeeTags())
						.set(null != v.getBusinessLeaveReason(), TBusinessEmployeeExtendInfo::getBusinessLeaveReason, v.getBusinessLeaveReason())
						.set(null != v.getBusinessWorkingStatus(), TBusinessEmployeeExtendInfo::getBusinessWorkingStatus, v.getBusinessWorkingStatus())
						.set(null != v.getDocumentType(), TBusinessEmployeeExtendInfo::getDocumentType, v.getDocumentType())
						.set(null != v.getBusinessLeaveDate(), TBusinessEmployeeExtendInfo::getBusinessLeaveDate, v.getBusinessLeaveDate())
						.update();
			}
		}
		return true;
	}
	/**
	 * 格式化标签id
	 *
	 * @param employeeTags 标签字符串，英文逗号分割
	 * @return: java.lang.String
	 * @author: wangweiguo
	 * @date: 2021/8/19
	 */
	public static String formatLabelId(String employeeTags) {
		// 标签id格式化处理
		String[] tags = StringUtils.split(employeeTags, ",");
		List<String> tagList = new ArrayList<>();
		if (null != tags) {
			for (String tag : tags) {
				tagList.add(String.format(CommonConstants.TAG_FROMAT, Integer.valueOf(tag)));
			}
		}
		return StringUtils.join(tagList, ",");
	}

	/**
	 * @description: 根据身份证号查询人员拓展表信息
	 * @param empIdcard 身份证号
	 * @return: com.yifu.cloud.v1.hrms.api.entity.basic.TBusinessEmployeeExtendInfo
	 * @author: wangweiguo
	 * @date: 2021/8/10
	 */
	@Override
	public TBusinessEmployeeExtendInfo getByEmpIdCard(String empIdcard) {
		if (StringUtils.isNotBlank(empIdcard)) {
			return this.lambdaQuery().eq(TBusinessEmployeeExtendInfo::getEmpIdcard, empIdcard).last(CommonConstants.LAST_ONE_SQL).one();
		}
		return null;
	}

	/**
	 * @param businessTelecomNumber
	 * @Description: 根据电信工号获取详情
	 * @Author: hgw
	 * @Date: 2021/8/18 17:04
	 * @return: com.yifu.cloud.v1.hrms.api.entity.basic.TBusinessEmployeeExtendInfo
	 **/
	@Override
	public TBusinessEmployeeExtendInfo getByBusinessTelecomNumber(String businessTelecomNumber) {
		if (StringUtils.isNotBlank(businessTelecomNumber)) {
			return this.lambdaQuery().eq(TBusinessEmployeeExtendInfo::getBusinessTelecomNumber, businessTelecomNumber).last(CommonConstants.LAST_ONE_SQL).one();
		}
		return null;
	}

	/**
	 * 根据jsonStr批量更新人员信息拓展表信息
	 * @description:
	 * @param jsonStr
	 * @param empInfoMap
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.Boolean>
	 * @author: wangweiguo
	 * @date: 2021/8/10
	 */
	@Override
	public R<List<ErrorMessage>> batchUpdateEmployeeExtendByJsonStr(String jsonStr, HashMap<String, TEmployeeProject> empInfoMap) {
		List<UpdateBusinessEmployeeExtendDTO> list = null;
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		try {
			list = objectMapper.readValue(jsonStr, new TypeReference<List<UpdateBusinessEmployeeExtendDTO>>(){});
		} catch (InvalidFormatException e) {
			e.printStackTrace();
			if (e.getCause().toString().contains("DateTimeParseException")) {
				errorMessageList.add(new ErrorMessage(e.getPath().get(0).getIndex() + 2, JSON_DATE_RESOLVER_ERROR.concat("错误值：" + e.getValue().toString())));
				return R.failed(errorMessageList);
			}
			errorMessageList.add(new ErrorMessage(e.getPath().get(0).getIndex() + 2, JSON_RESOLVER_ERROR.concat(e.getCause().toString())));
			return R.failed(errorMessageList);
		} catch (Exception e) {
			e.printStackTrace();
			errorMessageList.add(new ErrorMessage(null, e.getCause().toString()));
			return R.failed(errorMessageList);
		}
		if (!CollUtil.isEmpty(list)) {
			List<TBusinessEmployeeExtendInfo> dtoList = new ArrayList<>();

			TBusDept busDeptParam = new TBusDept();
			R<BusDeptVo> busDeptListR = HttpDaprUtil.invokeMethodPost(daprBusinessProperties.getAppUrl(), daprBusinessProperties.getAppId()
					, "/tbusdept/inner/getTBusDeptList", busDeptParam, BusDeptVo.class, SecurityConstants.FROM_IN);

			TBusLable busLableParam = new TBusLable();
			R<BusLableVo> busLableListR = HttpDaprUtil.invokeMethodPost(daprBusinessProperties.getAppUrl(), daprBusinessProperties.getAppId()
					, "/tbuslable/inner/getTBusLableList", busLableParam, BusLableVo.class, SecurityConstants.FROM_IN);
			if (!R.isSuccess(busDeptListR)) {
				errorMessageList.add(new ErrorMessage(null, busDeptListR.getMsg()));
				return R.failed(errorMessageList);
			}
			if (!R.isSuccess(busLableListR)) {
				errorMessageList.add(new ErrorMessage(null,busLableListR.getMsg()));
				return R.failed(errorMessageList);
			}
			if (CollUtil.isEmpty(busDeptListR.getData().getBusDeptList())) {
				errorMessageList.add(new ErrorMessage(null, DEPT_LIST_IS_NULL));
				return R.failed(errorMessageList);
			}
			if (CollUtil.isEmpty(busLableListR.getData().getBusLableList())) {
				errorMessageList.add(new ErrorMessage(null, LABEL_LIST_IS_NULL));
				return R.failed(errorMessageList);
			}

			List<ErrorMessage> beforeErrorMessageList = Common.commonImportErrorMessage(list);
			HashMap<String, TBusDept> busDeptMap = Common.listToHashMapByKey(busDeptListR.getData().getBusDeptList(), "name");
			HashMap<String, TBusLable> busLableMap = Common.listToHashMapByKey(busLableListR.getData().getBusLableList(), "name");
			HashMap<String, ErrorMessage> errorMessageHashMap = Common.listToHashMapByKey(beforeErrorMessageList, "line");

			List<TBusinessEmployeeExtendInfo> employeeExtendInfoList = TBusinessEmployeeExtendInfo.covertDtoListToList(list);
			// 导入数据校验
			errorMessageList.addAll(beforeErrorMessageList);
			if (!beforeErrorMessageList.isEmpty()) {
				return R.failed(errorMessageList);
			}
			// 数据导入
			boolean isSave;
			for (int i = 0; i < employeeExtendInfoList.size(); i++) {
				isSave = true;
				int line = i + 2;
				TBusinessEmployeeExtendInfo v = employeeExtendInfoList.get(i);
				TBusinessEmployeeExtendInfo entity = this.baseMapper.getDataByEmpIdcard(v.getEmpIdcard());
				if (null != entity) {
					v.setId(entity.getId());
					v.setEmpName(entity.getEmpName());
				}
				if (busDeptMap.containsKey(v.getDepartName())) {
					TBusDept busDept = busDeptMap.get(v.getDepartName());
					v.setDepartCode(busDept.getTreeLogo());
					v.setDepartId(busDept.getId());
				}
				ErrorMessage errorMessage = errorMessageHashMap.get(line + "");
				if (errorMessage != null) {
					continue;
				}
				// 部门是否存在判断
				if (!busDeptMap.containsKey(v.getDepartName())) {
					errorMessageList.add(new ErrorMessage(line, DEPT_NAME_IS_NOT_EXIST));
					isSave = false;
				}
				// 身份证是否存在hro系统判断
				if (!empInfoMap.containsKey(v.getEmpIdcard())) {
					errorMessageList.add(new ErrorMessage(line, ID_CARD_IS_NOT_EXIST));
					isSave = false;
				}

				// 标签判断，并处理
				if (StringUtils.isNotBlank(v.getEmployeeTags())) {
					List<String> tagList = new ArrayList<>();
					String[] tags = v.getEmployeeTags().split(",");
					for (String tag : tags) {
						TBusLable tBusLable = busLableMap.get(tag);
						if (null != tBusLable) {
							if (tBusLable.getStatus() != 0) {
								errorMessageList.add(new ErrorMessage(line, "[" + tBusLable.getName() + "]" + TAG_IS_BANED));
								isSave = false;
							}
							if (tBusLable.getStatus() == 0) {
								tagList.add(String.valueOf(tBusLable.getId()));
							} else {
								tagList.clear();
							}
						} else {
							errorMessageList.add(new ErrorMessage(line, "[" + tag + "]" + TAG_IS_NOT_EXIST));
							isSave = false;
						}
					}

					if (!CollUtil.isEmpty(tagList) && tagList.size() > 10) {
						errorMessageList.add(new ErrorMessage(line, EMPLOYEE_TAGS_EXCEED));
						isSave = false;
					}
					// 处理标签格式化
					List<String> tagFormatList  = new ArrayList<>();
					if (!CollUtil.isEmpty(tagList)) {
						tagList.forEach(tag -> tagFormatList.add(String.format("%04d", Integer.valueOf(tag))));
						v.setEmployeeTags(StringUtils.join(tagFormatList, ","));
					} else if (null != entity){
						v.setEmployeeTags(entity.getEmployeeTags());
					}
				}
				try {
					// 校验电信编号是否重复
					if (existBusinessTelecomNumber(v)) {
						errorMessageList.add(new ErrorMessage(line, TELECOMNUMBER_IS_EXIST));
						continue;
					}
					// 冗余的字段，岗位，工号变更要同步过去
					if (null != entity && isUpdateRedundancy(v, entity)) {
						dtoList.add(v);
					}
					if (!isSave) {
						continue;
					}
					boolean isSuccess = this.saveOrUpdate(v);
					if (!isSuccess) {
						errorMessageList.add(new ErrorMessage(line, CommonConstants.UPDATE_DATA_FAIL));
					} else {
						errorMessageList.add(new ErrorMessage(line, CommonConstants.UPDATE_SUCCESS, CommonConstants.GREEN));
					}
				} catch (Exception e) {
					errorMessageList.add(new ErrorMessage(null, BATCH_USER_EXTEND_DATA_ERROR + "：" + e.getCause().toString()));
					return R.failed(BATCH_USER_EXTEND_DATA_ERROR + "：" + e.getCause().toString());
				}
			}
			this.updateRedundancyEmployeeFields(dtoList);
		}
		if (CollUtil.isEmpty(errorMessageList)) {
			return R.failed(CommonConstants.NO_DATA_TO_HANDLE);
		}
		return R.ok(errorMessageList);
	}

	/**
	 * 是否更新冗余字段
	 * @param v 当前值
	 * @param entity 原有值
	 * @return boolean
	 */
	private boolean isUpdateRedundancy(TBusinessEmployeeExtendInfo v, TBusinessEmployeeExtendInfo entity) {
		if (!StringUtils.equals(v.getBusinessTelecomNumber(), entity.getBusinessTelecomNumber())
				|| !StringUtils.equals(v.getBusinessPost(), entity.getBusinessPost())
				|| !StringUtils.equals(v.getEmpName(), entity.getEmpName())
				|| !(Objects.equals(v.getDepartId(), entity.getDepartId()))
		){
			return true;
		}
		return false;
	}

	/**
	 * 根据身份证号获取拓展信息列表
	 * @description: 根据身份证号获取拓展信息列表
	 * @param idCardList
	 * @return: com.yifu.cloud.v1.common.core.util.R<List<TBusinessEmployeeExtendInfo>>
	 * @author: wangweiguo
	 * @date: 2021/8/16
	 */
	@Override
	public List<TBusinessEmployeeExtendInfo> getListByIdCardList(List<String> idCardList) {
		List<TBusinessEmployeeExtendInfo> list = this.lambdaQuery().in(TBusinessEmployeeExtendInfo::getEmpIdcard, idCardList).list();
		return list;
	}

	/**
	 * 查询-列表：内部服务调用，获取所有非离职员工拓展表信息
	 * @description: 查询-列表：内部服务调用，获取所有非离职员工拓展表信息
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.util.List<com.yifu.cloud.v1.hrms.api.vo.basic.BusinessEmployeeExtendVO>>
	 * @author: wangweiguo
	 * @date: 2021/8/17
	 */
	@Override
	public TBusinessDataListVo getNotLeaveExtendList() {
		List<BusinessEmployeeExtendVO> list = this.baseMapper.getNotLeaveExtendList();
		TBusinessDataListVo vo = new TBusinessDataListVo();
		vo.setExtendVO(list);
		return vo;
	}

	/**
	 * @param
	 * @Description: 获取所有扩展信息-不要离职的
	 * @Author: hgw
	 * @Date: 2021/8/18 16:41
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.util.Map < java.lang.String, com.yifu.cloud.v1.hrms.api.vo.basic.BusinessEmployeeExtendByLeave>>
	 **/
	@Override
	public Map<String, BusinessEmployeeExtendByLeave> getInfoByLeaveMap() {
		List<BusinessEmployeeExtendByLeave> list = this.baseMapper.getInfoByLeaveList();
		Map<String, BusinessEmployeeExtendByLeave> leaveMap = new HashMap<>();
		if (list != null && !list.isEmpty()) {
			for (BusinessEmployeeExtendByLeave leave : list) {
				leaveMap.put(leave.getBusinessTelecomNumber(), leave);
			}
		}
		return leaveMap;
	}

	/**
	 * b端人员信息编辑拓展信息
	 * @description: b端人员信息编辑拓展信息
	 * @param entity 实体
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.Boolean>
	 * @author: wangweiguo
	 * @date: 2021/8/19
	 */
	@Override
	public R<Boolean> saveOrUpdateData(TBusinessEmployeeExtendInfo entity) {
		if (existBusinessTelecomNumber(entity)) {
			return R.failed(TELECOMNUMBER_IS_EXIST);
		}

		// 标签id格式化
		entity.setEmployeeTags(formatLabelId(entity.getEmployeeTags()));
		int tagSize = StringUtils.split(entity.getEmployeeTags(), ",").length;
		if (tagSize > 10) {
			return R.failed(EMPLOYEE_TAGS_EXCEED);
		}
		boolean isSuccess = this.saveOrUpdate(entity);
		if (isSuccess) {
			this.updateRedundancyEmployeeFields(CollUtil.newArrayList(entity));
		}
		return R.ok();
	}

	@Transactional
	@Override
	public boolean updateEmpExtendCertInfo(UpdateEmployeeExtendRedundancyDTO v) {
		if (Common.isEmpty(v)) {
			return false;
		}
		// 根据部门id更新冗余的部门信息
		if (null != v.getDepartId()) {
			this.lambdaUpdate()
					.eq(TBusinessEmployeeExtendInfo::getDepartId, v.getDepartId())
					.set(TBusinessEmployeeExtendInfo::getDepartName, v.getDepartName())
					.set(TBusinessEmployeeExtendInfo::getDepartCode, v.getTreeLogo())
					.update();
		} else {
			if (StringUtils.isBlank(v.getEmpIdcard())) {
				return false;
			}
			// 身份证号更新冗余的离职，标签，证件相关信息
			return this.lambdaUpdate()
					.eq(TBusinessEmployeeExtendInfo::getEmpIdcard, v.getEmpIdcard())
					.set(TBusinessEmployeeExtendInfo::getDocumentType, v.getDocumentType())
					.update();
		}
		return true;
	}

	@Override
	public TBusinessEmployeeExtendInfo getDataById(String extendId) {
		return this.baseMapper.getDataById(extendId);
	}

	/**
	 * @description: 是否存在电信编号
	 * @param info 实体
	 * @return: boolean
	 * @author: wangweiguo
	 * @date: 2021/8/19
	 */
	private boolean existBusinessTelecomNumber(TBusinessEmployeeExtendInfo info) {
		TBusinessEmployeeExtendInfo entity = this.lambdaQuery().eq(TBusinessEmployeeExtendInfo::getBusinessTelecomNumber, info.getBusinessTelecomNumber()).last(CommonConstants.LAST_ONE_SQL).one();
		if (null != entity && !StringUtils.equals(entity.getId(), info.getId())) {
			return true;
		}
		return false;
	}

	/**
	 * @description: 更新其他表冗余字段
	 * @param list
	 * @return: void
	 * @author: wangweiguo
	 * @date: 2021/8/23
	 */
	private void updateRedundancyEmployeeFields(List<TBusinessEmployeeExtendInfo> list) {
		List<UpdateVacationRedundancyDTO> dtoList = new ArrayList<>();
		if (!CollUtil.isEmpty(list)) {
			list.forEach(v -> {
				UpdateVacationRedundancyDTO dto = new UpdateVacationRedundancyDTO(v.getEmpIdcard(), v.getEmpName(), v.getBusinessTelecomNumber(), v.getBusinessPost(), v.getDepartId(),v.getEmployeeTags());
				dtoList.add(dto);
			});
			HttpDaprUtil.invokeMethodPost(daprBusinessProperties.getAppUrl(), daprBusinessProperties.getAppId()
					, "/vacationInfo/inner/updateRedundancyEmployeeFields", dtoList, Object.class, SecurityConstants.FROM_IN);
			HttpDaprUtil.invokeMethodPost(daprBusinessProperties.getAppUrl(), daprBusinessProperties.getAppId()
					, "/vacationMonitor/inner/updateRedundancyEmployeeFields", dtoList, Object.class, SecurityConstants.FROM_IN);
			HttpDaprUtil.invokeMethodPost(daprBusinessProperties.getAppUrl(), daprBusinessProperties.getAppId()
					, "/tcertinfo/inner/updateRedundancyEmpOfCert", dtoList, Object.class, SecurityConstants.FROM_IN);
		}
	}

}




