/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.archives.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.AreaMap;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.SysUserListVo;
import com.yifu.cloud.plus.v1.yifu.archives.constants.ArchivesConstants;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCutsomerDataPermisson;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TSettleDomain;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TCutsomerDataPermissonMapper;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TSettleDomainMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.TSettleDomainService;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.util.RedisUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.UpmsDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.mybatis.base.BaseEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目表
 *
 * @author hgw
 * @date 2022-06-20 10:02:28
 */
@Service
@RequiredArgsConstructor
public class TSettleDomainServiceImpl extends ServiceImpl<TSettleDomainMapper, TSettleDomain> implements TSettleDomainService {
	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private UpmsDaprUtils upmsDaprUtils;

	private final TCutsomerDataPermissonMapper permissonMapper;

	@Override
	public IPage<TSettleDomain> getPage(Page<TSettleDomain> page, TSettleDomain tSettleDomain) {
		return baseMapper.getPage(page, tSettleDomain);
	}

	@Override
	public IPage<SecondBelongVo> getTwoBlongPage(Page<TSettleDomain> page, TSettleDomain tSettleDomain) {
		return baseMapper.getTwoBlongPage(page, tSettleDomain);
	}

	@Override
	public List<TSettleDomain> getList(TSettleDomain tSettleDomain) {
		return baseMapper.getPage(tSettleDomain);
	}

	@Override
	public IPage<IdNameNoVo> getUnitPage(Page<IdNameNoVo> page, IdNameNoVo idNameNoVo) {
		return baseMapper.getUnitPage(page, idNameNoVo);
	}
	private final CacheManager cacheManager;
	/**
	 * @Author fxj
	 * @Description 清除项目缓存
	 * @Date 17:08 2022/7/11
	 * @Param
	 * @return
	**/
	@Override
	public void removeSettleCache(YifuUser user, List<String> userIdList) {
		try{
			for(String userId : userIdList){
				redisUtil.remove(CacheConstants.WXHR_SETTLE_DOMAIN_VOS_BY_USERID +"_"+userId);
				redisUtil.remove(CacheConstants.WXHR_SETTLE_DOMAIN_NOS_BY_USERID +"_"+userId);
				redisUtil.remove(CacheConstants.DATA_AUTH_DETAILS +"_0");
				redisUtil.remove(CacheConstants.DATA_AUTH_DETAILS +"_1");
				if (Common.isNotNull(user)){
					redisUtil.remove(CacheConstants.USER_DETAILS +"::"+ user.getUsername());
					if( Common.isNotNull(user.getPhone())){
						redisUtil.remove(CacheConstants.USER_DETAILS + "_phone::"+ user.getPhone());
					}
				}
				// 清空userinfo
				Objects.requireNonNull(cacheManager.getCache(CacheConstants.USER_DETAILS)).clear();
			}
		} catch (Exception e) {
			log.error("清除缓存错误：",e);
		}
	}

	@Override
	public List<String> getSettleDomainIdsByUserId(String userId) {
		List<String> domainIds = new ArrayList<>();
		String userKey = CacheConstants.WXHR_SETTLE_DOMAIN_VOS_BY_USERID + "_" + userId;
		Object settleDomainVoR = redisUtil.get(userKey);
		if (settleDomainVoR != null) {
			return (List<String>) settleDomainVoR;
		} else {
			List<TCutsomerDataPermisson>  permissonList = permissonMapper.selectAllSettleDomainPermissionByUserId(userId);
			if (Common.isNotNull(permissonList)) {
				domainIds = permissonList.stream().map(TCutsomerDataPermisson::getSettleDomainId).collect(Collectors.toList());
				redisUtil.set(userKey, domainIds);
			}
		}
		return domainIds;
	}

	/**
	 * 获取用户所拥有的项目编码
	 *
	 * @param userId 用户id
	 */
	@Override
	public List<String> getSettleDomainNosByUserId(String userId) {
		List<String> domainNos = new ArrayList<>();
		String userKey = CacheConstants.WXHR_SETTLE_DOMAIN_NOS_BY_USERID + "_" + userId;
		Object settleDomainVoR = redisUtil.get(userKey);
		if (settleDomainVoR != null) {
			return (List<String>) settleDomainVoR;
		} else {
			List<TCutsomerDataPermisson>  permissonList = permissonMapper.selectAllSettleDomainPermissionByUserId(userId);
			if (Common.isNotNull(permissonList)) {
				domainNos = permissonList.stream().map(TCutsomerDataPermisson::getSettleDomainNo).collect(Collectors.toList());
				redisUtil.set(userKey, domainNos);
			}
		}
		return domainNos;
	}

	/**
	 * @param settleDomainSelectVo
	 * @Author: wangan
	 * @Date: 2019/10/18
	 * @Description: dataCheckDepart
	 * @return: com.yifu.cloud.v1.hrms.api.vo.TSettleDomainSelectVo
	 **/
	@Override
	public TSettleDomainSelectVo selectSettleDomainSelectVosById(TSettleDomainSelectVo settleDomainSelectVo) {
		return baseMapper.selectSettleDomainSelectVosById(settleDomainSelectVo.getDepartNo());
	}

	@Override
	public TSettleDomainSelectVo getSettleDomainVoById(String id) {
		return baseMapper.getSettleDomainVoById(id);
	}

	@Override
	public List<TSettleDomainSelectVo> selectAllSettleDomainSelectVos() {
		return baseMapper.selectAllSettleDomainSelectVos();
	}

	@Transactional
	@Override
	public R updateProjectInfo(List<TSettleDomainEkpVo> list) {
		if (Common.isNotNull(list)) {
			R<AreaMap> areaListR;
			TSettleDomain tSettleDomainInfo;

			areaListR = upmsDaprUtils.getAreaMapR();
			if (null == areaListR
					|| areaListR.getCode() != CommonConstants.SUCCESS
					|| Common.isEmpty(areaListR.getData())) {
				return R.failed("获取区域数据失败！");
			}
			Map<String,String> areaMap = areaListR.getData().getLabelIdMap();
			String errorStr;
			TSettleDomain domain;
			for (TSettleDomainEkpVo vo:list) {
				domain = new TSettleDomain();
				BeanUtil.copyProperties(vo,domain);
				// 校验必填项
				errorStr = checkInfo(domain);
				if (Common.isNotNull(errorStr)){
					return R.failed(errorStr);
				}
				// 初始化区域数据
				R<Object> tSettleDomain1 = initAreaInfo(areaMap, domain);
				if (tSettleDomain1 != null){
					return tSettleDomain1;
				}
				tSettleDomainInfo = baseMapper.selectOne(Wrappers.<TSettleDomain>query().lambda()
						.eq(TSettleDomain::getDepartNo,domain.getDepartNo())
						.orderByDesc(BaseEntity::getCreateTime)
						.last(CommonConstants.LAST_ONE_SQL));
				if (Common.isNotNull(tSettleDomainInfo)) {
					domain.setId(tSettleDomainInfo.getId());
				}
				// 处理服务团队数据权限 2022-09-19 fxj
				initServerTeamPermission(domain);
				domain.setDeleteFlag(CommonConstants.ZERO_STRING);
				log.error(JSON.toJSONString(vo));
				if (Common.isNotNull(tSettleDomainInfo)) {
					baseMapper.updateById(domain);
					baseMapper.updateHistoryData(domain.getDepartNo());

				} else {
					baseMapper.insert(domain);
					baseMapper.updateHistoryData(domain.getDepartNo());
				}
			}
			return R.ok();
		} else {
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
	}

	@Override
	public R updateProjectStopStatus(List<TSettleDomainUpdVo> list) {
		if (Common.isNotNull(list)) {
			TSettleDomain settleDomain;
			for (TSettleDomainUpdVo settleDomainUpdVo : list) {
				if (Common.isEmpty(settleDomainUpdVo.getDepartNo()) ||
						Common.isEmpty(settleDomainUpdVo.getStopFlag())) {
					return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
				}
				if (!CommonConstants.ONE_STRING.equals(settleDomainUpdVo.getStopFlag()) &&
						!CommonConstants.TWO_STRING.equals(settleDomainUpdVo.getStopFlag()) &&
						!CommonConstants.ZERO_STRING.equals(settleDomainUpdVo.getStopFlag())) {
					return R.failed("服务状态传参错误");
				}
				settleDomain = baseMapper.selectOne(Wrappers.<TSettleDomain>query().lambda()
						.eq(TSettleDomain::getDepartNo, settleDomainUpdVo.getDepartNo())
						.eq(TSettleDomain::getDeleteFlag, CommonConstants.ZERO_STRING)
						.last(CommonConstants.LAST_ONE_SQL));
				if (Common.isEmpty(settleDomain)) {
					return R.failed("不存在该项目");
				}
				if (settleDomain.getStopFlag().equals(settleDomainUpdVo.getStopFlag())) {
					return R.failed("不可重复变更项目服务状态");
				}
				settleDomain.setStopFlag(settleDomainUpdVo.getStopFlag());
				baseMapper.updateById(settleDomain);
			}
			return R.ok();
		}else {
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
	}

	private String checkInfo(TSettleDomain domain) {
		if (Common.isEmpty(domain.getId())){
			return ArchivesConstants.SETTLE_DOMAIN_ID_NOT_EMPTY;
		}
		if (Common.isEmpty(domain.getDepartName())|| Common.isEmpty(domain.getDepartNo())){
			return ArchivesConstants.SETTLE_DOMAIN_NAME_AND_NO_NOT_EMPTY;
		}
		if (Common.isEmpty(domain.getCustomerName())
				|| Common.isEmpty(domain.getCustomerId())
				|| Common.isEmpty(domain.getCustomerNo())){
			return ArchivesConstants.SETTLE_DOMAIN_CUSTOMER_INFO_NOT_EMPTY;
		}
		if (Common.isEmpty(domain.getBpoFlag())){
			return ArchivesConstants.SETTLE_DOMAIN_BPO_FLAG_NOT_EMPTY;
		}
		if (Common.isEmpty(domain.getServerItem())){
			return ArchivesConstants.SETTLE_DOMAIN_SERVER_ITEM_NOT_EMPTY;
		}
		if (Common.isEmpty(domain.getECity())
				|| Common.isEmpty(domain.getEProvince())){
			return ArchivesConstants.SETTLE_DOMAIN_PROVINCE_NOT_EMPTY;
		}
		/*if ( Common.isEmpty(domain.getCreateType())){
			return "创建类型不可为空";
		}*/
		if (Common.isEmpty(domain.getBusinessPrimaryType())
				|| Common.isEmpty(domain.getBusinessSecondType())
				|| Common.isEmpty(domain.getBusinessThirdType())){
			return ArchivesConstants.SETTLE_DOMAIN_BUSINESS_TYPE_NOT_EMPTY;
		}
		if (Common.isEmpty(domain.getStopFlag())){
			return ArchivesConstants.SETTLE_DOMAIN_STOP_FLAG_NOT_EMPTY;
		}
				/*
				我司到款单位名称	条件：当服务项目中有社保或公积金时必填
				封面抬头-薪资	条件：当服务项目中有薪资时必填
				封面抬头-商险	条件：当服务项目中有商险时必填  */
		if (Common.isNotNull(domain.getServerItem())){
			if (domain.getServerItem().indexOf(ArchivesConstants.SETTLE_DOMAIN_SOCIAL) != CommonConstants.ONE_INT_NEGATE){
				if (Common.isEmpty(domain.getSocialType())){
					return  ArchivesConstants.SETTLE_DOMAIN_SOCIAL_TYPE_NOT_EMPTY;
				}
				if (Common.isEmpty(domain.getUnitOfOurCompany())){
					return  ArchivesConstants.SETTLE_DOMAIN_UNIT_OUT_COMPANY_NOT_EMPTY;
				}
			}
			if (domain.getServerItem().indexOf(ArchivesConstants.SETTLE_DOMAIN_FUND) != CommonConstants.ONE_INT_NEGATE){
				if (Common.isEmpty(domain.getFundType())){
					return  ArchivesConstants.SETTLE_DOMAIN_FUND_TYPE_NOT_EMPTY;
				}
				if (Common.isEmpty(domain.getUnitOfOurCompany())){
					return  ArchivesConstants.SETTLE_DOMAIN_UNIT_OUT_COMPANY_NOT_EMPTY;
				}
			}
			if (domain.getServerItem().indexOf(ArchivesConstants.SETTLE_DOMAIN_SALARY) != CommonConstants.ONE_INT_NEGATE){
				if (Common.isEmpty(domain.getInvoiceTitleSalary())){
					return  ArchivesConstants.SETTLE_DOMAIN_INVOICE_TITLE_NOT_EMPTY;
				}
			}
			if (domain.getServerItem().indexOf(ArchivesConstants.SETTLE_DOMAIN_INSURANCES) != CommonConstants.ONE_INT_NEGATE){
				if (Common.isEmpty(domain.getInsuranceSettleType())){
					return  ArchivesConstants.SETTLE_DOMAIN_INSURANCE_SETTLE_TYPE_NOT_EMPTY;
				}
				if (Common.isEmpty(domain.getInvoiceTitleInsurance())){
					return  ArchivesConstants.SETTLE_DOMAIN_INSURANCE_TITLE_NOT_EMPTY;
				}
			}
		}
		if (Common.isEmpty(domain.getManagementTag()) || Common.isEmpty(domain.getRiskFundTag())){
			return  ArchivesConstants.SETTLE_DOMAIN_MANAGEMENT_AND_RISK_TAG_NOT_EMPTY;
		}
		if (CommonConstants.ZERO_STRING.equals(domain.getManagementTag())
				&& (Common.isEmpty(domain.getManageServerItem())
				|| Common.isEmpty(domain.getManagementFee())
				|| Common.isEmpty(domain.getManagementType()))){
			return ArchivesConstants.SETTLE_DOMAIN_MANAGEMENT_INFO_NOT_EMPTY;
		}
		if (CommonConstants.ZERO_STRING.equals(domain.getRiskFundTag())
				&& (Common.isEmpty(domain.getRiskServerItem())
				|| Common.isEmpty(domain.getRiskFundType())
				|| Common.isEmpty(domain.getRiskFundFee()))){
			return ArchivesConstants.SETTLE_DOMAIN_RISK_INFO_NOT_EMPTY;
		}
		if (Common.isEmpty(domain.getMrSettleType())){
			return ArchivesConstants.SETTLE_DOMAIN_SETTLE_TYPE_NOT_EMPTY;
		}
		return  null;
	}

	private R<Object> initAreaInfo(Map<String, String> areaMap, TSettleDomain tSettleDomain) {
		String areaId;
		if (Common.isNotNull(areaMap)) {
			if (Common.isNotNull(tSettleDomain.getEProvince())){
				areaId = areaMap.get(tSettleDomain.getEProvince());
				if (Common.isNotNull(areaId)){
					tSettleDomain.setProvince(Integer.parseInt(areaId));
				}else {
					return R.failed(ArchivesConstants.SETTLE_DOMAIN_CHECK_AREA_NOT_EXISTS + tSettleDomain.getEProvince());
				}
			}
			if (Common.isNotNull(tSettleDomain.getECity())){
				areaId = areaMap.get(tSettleDomain.getECity()+CommonConstants.DOWN_LINE_STRING+tSettleDomain.getEProvince());
				if (Common.isNotNull(areaId)){
					tSettleDomain.setCity(Integer.parseInt(areaId));
				}else {
					return R.failed(ArchivesConstants.SETTLE_DOMAIN_CHECK_AREA_NOT_EXISTS + tSettleDomain.getECity());
				}
			}
			if (Common.isNotNull(tSettleDomain.getETown())){
				areaId = areaMap.get(tSettleDomain.getETown()+CommonConstants.DOWN_LINE_STRING+tSettleDomain.getECity());
				if (Common.isNotNull(areaId)){
					tSettleDomain.setTown(Integer.parseInt(areaId));
				}else {
					return R.failed(ArchivesConstants.SETTLE_DOMAIN_CHECK_AREA_NOT_EXISTS + tSettleDomain.getETown());
				}
			}
		}
		return null;
	}

	@Override
	public SetInfoVo getSetInfoByCodes(List<String> codes) {
		List<ProjectSetInfoVo> voList = baseMapper.getSetInfoByCodes(codes);
		SetInfoVo setMap = new SetInfoVo();
		if (Common.isNotNull(voList)){
			setMap.setProjectSetInfoVoMap(voList.stream().collect(Collectors.toMap(k->k.getDepartNo(),k->k)));
		}
		return setMap;
	}

	@Override
	public TSettleDomainListVo getSettleInfoByCodes(List<String> codes) {
		List<TSettleDomain> voList = baseMapper.getSettleInfoByCodes(codes);
		TSettleDomainListVo setMap = new TSettleDomainListVo();
		if (Common.isNotNull(voList)){
			setMap.setMapVO(voList.stream().collect(Collectors.toMap(TSettleDomain::getDepartNo, k->k)));
		}
		return setMap;
	}

	/**
	 * @Author fxj
	 * @Description 更新EKP对应MVP 项目权限，已有权限不做删除处理
	 * @Date 17:17 2022/9/19
	 * @Param
	 * @return
	 **/
	public  boolean saveForEkp(List<SysUser> userIds, TSettleDomain domain){
		// 1. 先清除现有的这些人的项目权限
		permissonMapper.delete(Wrappers.<TCutsomerDataPermisson>query().lambda()
				.in(TCutsomerDataPermisson::getUserId,userIds)
				.eq(TCutsomerDataPermisson::getSettleDomainId,domain.getId()));
		// 2.新增新的项目人员权限
		TCutsomerDataPermisson pm;
		if (Common.isNotNull(userIds)) {
			for (SysUser user : userIds){
				pm = new TCutsomerDataPermisson();
				pm.setStatus(CommonConstants.ZERO_STRING);
				pm.setUserId(user.getUserId());
				pm.setUserLoginName(user.getUsername());
				pm.setUserNickName(user.getNickname());
				pm.setUserDeptName(user.getDeptName());
				pm.setCreateTime(LocalDateTime.now());
				pm.setSettleDomainId(domain.getId());
				pm.setSettleDomainName(domain.getDepartName());
				pm.setSettleDomainNo(domain.getDepartNo());
				pm.setCreateBy(CommonConstants.ONE_STRING);
				pm.setCreateName("EKP同步");
				pm.setType(CommonConstants.ZERO_STRING);
				permissonMapper.insert(pm);
			}
		}
		return true;
	}
	@Override
	public List<TSettleDomain> getOwnSettleDomainNoPage(String userId, String settleName) {
		if(Common.isNotNull(userId)){
			return baseMapper.getOwnSettleDomainNoPage(userId,settleName);
		}
		return Collections.emptyList();
	}
	@Override
	public R<IPage<TSettleDomainVo>> getOwnSettleDomain(Page<TSettleDomainVo> page, String userId, String name) {
		if(Common.isNotNull(userId)){
			return R.ok(baseMapper.getOwnSettleDomain(page,userId,name),CommonConstants.RESULT_DATA_SUCESS);
		}
		return (R<IPage<TSettleDomainVo>>) Collections.emptyList();
	}

	@Override
	public R<IPage<TCustomerInfo>> getTCustomerInfoPageForB(Page<TCustomerInfo> page, TCustomerInfo tCustomerInfo) {
		return R.ok(baseMapper.getTCustomerInfoPageForB(page,tCustomerInfo));
	}

	@Override
	public R<IPage<TSettleDomainVo>> getTSettleDomainPageB(Page<TSettleDomainVo> page, TSettleDomainVo tSettleDomain) {
		return R.ok(baseMapper.getTSettleDomainPageB(page,tSettleDomain));
	}

	@Override
	public List<TCustomerInfo> getTCustomerInfoForB(List<String> customerList) {
		if (Common.isNotNull(customerList)){
			return baseMapper.getTCustomerInfoForB(customerList);
		}
		return null;
	}

	@Override
	public R<IPage<CustomerOwnerSelectVo>> getCustomerOwnerPage(Page<CustomerOwnerSelectVo> page, String customerName,
																String userId) {
		return R.ok(baseMapper.getCustomerOwnerPage(page,customerName,userId));
	}
	/**
	 * @Author fxj
	 * @Description 更新服务团队人员权限
	 * @Date 11:23 2023/2/3
	**/
	@Override
	public R<Boolean> updateProjectServerTeam(List<TSettleDomainUpServerTeamVo> list) {
		TSettleDomain domain;
		TSettleDomain tSettleDomainInfo;
		for (TSettleDomainUpServerTeamVo vo:list) {
			domain = new TSettleDomain();
			BeanUtil.copyProperties(vo,domain);
			tSettleDomainInfo = baseMapper.selectOne(Wrappers.<TSettleDomain>query().lambda()
					.eq(TSettleDomain::getDepartNo,domain.getDepartNo())
					.orderByDesc(BaseEntity::getCreateTime)
					.last(CommonConstants.LAST_ONE_SQL));
			if (Common.isNotNull(tSettleDomainInfo)){
				domain.setDepartName(tSettleDomainInfo.getDepartName());
				domain.setId(tSettleDomainInfo.getId());
				initServerTeamPermission(domain);
			}
		}
		return R.ok(Boolean.TRUE,CommonConstants.RESULT_DATA_SUCESS);
	}

	private void initServerTeamPermission(TSettleDomain domain) {
		if (Common.isNotNull(domain.getServiceTeam())){
			R<SysUserListVo> res = upmsDaprUtils.getUserIdsByUserNames(domain.getServiceTeam());
			if (Common.isNotNull(res) && Common.isNotNull(res.getData()) && Common.isNotNull(res.getData().getUserList())){
				// 先清理缓存
				this.removeSettleCache(null, res.getData().getUserIds());
				saveForEkp(res.getData().getUserList(), domain);
			}
		}
	}
}
