/*
 *    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.social.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.excel.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.SysUserListVo;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.SysUsersVo;
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.DateUtil;
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.util.UpmsDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.mybatis.base.BaseEntity;
import com.yifu.cloud.plus.v1.yifu.social.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSocialAlertInfo;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TSocialAlertInfoMapper;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TSocialfundHouseResMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.TSocialAlertInfoService;
import com.yifu.cloud.plus.v1.yifu.social.vo.TSocialAlertInfoSearchVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TSocialAlertInfoVo;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author fxj
 * @date 2025-10-15 14:50:53
 */
@Log4j2
@Service
public class TSocialAlertInfoServiceImpl extends ServiceImpl<TSocialAlertInfoMapper, TSocialAlertInfo> implements TSocialAlertInfoService {
	@Autowired
	private UpmsDaprUtils upmsDaprUtils;

	@Autowired
	private TSocialfundHouseResMapper houseResMapper;

	@Autowired
	private WxConfig wxConfig;
	/**
	 * @Author fxj
	 * @Description 生成社保失败通知信息 并发送相关人:
	 * 1. 查询所有的社保失败通知信息
	 * 2. 获取所有的申请人信息并找到申请人信息有问题的地市办理人
	 * 3. 获取申请人对应的失败类型及条数，获取申请人账号有问题的地市办理人需要的通知人信息
	 * 4. 发送通知信息
	 * @Date 15:27 2025/10/15
	 * @Param
	 * @return
	**/
	@Override
	public void createAndSendSocialAlert() {
		//删除创建时间大于等于当日零点的数据
		baseMapper.deleteCUrrentDayData();
		List<TSocialAlertInfo> backList = new ArrayList<>();
		List<TSocialAlertInfo> backSocialList= baseMapper.getTSocialAlertInfoList();
		if (backSocialList != null && backSocialList.size() > 0){
			backList.addAll(backSocialList);
		}
		List<TSocialAlertInfo> backFundList = baseMapper.getTFundAlertInfoList();
		if (backFundList != null && backFundList.size() > 0){
			backList.addAll(backFundList);
		}
		if (backList != null && backList.size() > 0){
			this.saveBatch(backList);
			// 获取backList中所有的receiveUser信息且去重后逗号拼接到字符串userIds
			Set<String> userIdSet = new HashSet<>();
			for (TSocialAlertInfo item : backList) {
				if (item.getReceiveUser() != null && !"".equals(item.getReceiveUser())) {
					userIdSet.add(item.getReceiveUser());
				}
			}
			// 获取所有的申请人信息
			String userIds = userIdSet.stream()
					.filter(Objects::nonNull)
					.collect(Collectors.joining(CommonConstants.COMMA_STRING));
			Map<String,SysUser> userList = new HashMap<>();
			if (userIds.length() > 0){
				R<SysUsersVo> res = upmsDaprUtils.getInUseUserByIds(userIds);
				if (Common.isNotNull(res) && Common.isNotNull(res.getData()) && Common.isNotNull(res.getData().getUserList())) {
					userList = res.getData().getUserList();
				}
			}
			//找出不在userList中的数据或userList有数据但是lockFlag 不等于0 或 userList有数据但是wxMessage为空
			List<TSocialAlertInfo> backList2 = new ArrayList<>();
			for (TSocialAlertInfo item : backList) {
				SysUser user = userList.get(item.getReceiveUser());
				if (user == null || !CommonConstants.ZERO_STRING.equals(user.getLockFlag()) || Common.isEmpty(user.getWxMessage())) {
					backList2.add(item);
				}
			}
			//找出backList中不在backList2中的数据放到backList3中
			Set<TSocialAlertInfo> backList2Set = new HashSet<>(backList2);
			List<TSocialAlertInfo> backList3 = new ArrayList<>();
			for (TSocialAlertInfo item : backList) {
				if (!backList2Set.contains(item)) {
					backList3.add(item);
				}
			}
			//backList2中的数据按户统计，
			Map<String, List<TSocialAlertInfo>> houseHoldMap = backList2.stream()
					.filter(item -> item.getHouseHoldName() != null)
					.collect(Collectors.groupingBy(TSocialAlertInfo::getHouseHoldName));
			//循环houseHoldMap 统计出每户有多少人，同时每户按receiveUser去重
			Map<String, Integer> houseHoldCountMap = new HashMap<>();
			//循环houseHoldCountMap 取出每个户对应List<TSocialAlertInfo> 的CREATE_NAME，按handleTime倒序后的五个申请人的姓名,以逗号分隔
			Map<String, String > houseHoldNameMap = new HashMap<>();
			for (Map.Entry<String, List<TSocialAlertInfo>> entry : houseHoldMap.entrySet()) {
				String key = entry.getKey();
				List<TSocialAlertInfo> list = entry.getValue();
				if (null != list && list.size() > 0){
					List<String> receiveUserList = list.stream().map(TSocialAlertInfo::getReceiveUser).distinct().collect(Collectors.toList());
					houseHoldCountMap.put(key, receiveUserList.size());
					String applyNames = list.stream()
							.sorted(Comparator.comparing(TSocialAlertInfo::getHandleTime).reversed())
							.map(TSocialAlertInfo::getApplyName).distinct().limit(5).collect(Collectors.joining(","));
					houseHoldNameMap.put(key, applyNames);
				}
			}

			//backList3中找出Type为0的数据，然后按用户分类统计出对应的数量
			Map<String, Long> socialCountMap = backList3.stream()
					.filter(item -> item.getSocialProvince() != null)
					.collect(Collectors.groupingBy(TSocialAlertInfo::getReceiveUser, Collectors.counting()));
			Map<String, Long> fundCountMap = backList3.stream()
					.filter(item -> item.getFundProvince() != null)
					.collect(Collectors.groupingBy(TSocialAlertInfo::getReceiveUser, Collectors.counting()));
			//将socialCountMap和fundCountMap 按key 整合到一起，value为 value1 +':'+ value2; 需要考虑 socialCountMap 有fundCountMap中没有的或fundCountMap有socialCountMap中没有的情况
			Map<String, StringBuilder> countMap = new HashMap<>();
			Set<String> allKeys = new HashSet<>();
			allKeys.addAll(socialCountMap.keySet());
			allKeys.addAll(fundCountMap.keySet());
			Long socialCount;
			Long fundCount;
			StringBuilder message;
			for (String key : allKeys) {
				socialCount = socialCountMap.getOrDefault(key, 0L);
				fundCount = fundCountMap.getOrDefault(key, 0L);
				message = new StringBuilder();
				//提示信息拼接，社保公积金都有值提示：当前存在社保派单失败数量：10，当前存在公积金派单失败数量：10。请及时至HRO系统进行处理
				//提示信息社保没有值提示：当前存在派单失败数量：10。请及时至HRO系统进行处理
				//提示信息公积金没有值提示：当前存在公积金派单失败数量：10。请及时至HRO系统进行处理
				boolean hasAppend = false;
				if (socialCount > 0) {
					message.append("当前存在社保派单失败数量：")
					       .append(socialCount);
					hasAppend = true;
				}
				if (fundCount > 0) {
					if (hasAppend) {
						message.append("，");
					}
					message.append("当前存在公积金派单失败数量：")
					       .append(fundCount);
				}
				message.append("。请及时至HRO系统进行处理");
				countMap.put(key, message);
			}
			
			//循环houseHoldCountMap 找出每户地市的办理人账号信息，如果没有就丢弃
			//获取所有 TSocialFundHouseRes 以户名称为key，userId 为值，返回map
			List<Map<String, String>> houseResList = houseResMapper.getHouseHoldUserMap();
			Map<String, String> houseHoldUserMap = new HashMap<>();
			if (houseResList != null && houseResList.size() > 0){
				for (Map<String, String> item : houseResList) {
					houseHoldUserMap.put(item.get("key"), item.get("value"));
				}
			}
			// 取出houseHoldUserMap中所有的value 放到StringBuilder 中,并以逗号分隔
			StringBuilder sendUserIds = new StringBuilder();
			if (houseHoldMap != null && houseHoldMap.size() > 0){
				if (houseHoldUserMap != null && houseHoldUserMap.size() > 0){
					for (String key : houseHoldMap.keySet()) {
						if (null != houseHoldUserMap.get(key)){
							if (sendUserIds.length() == 0) {
								sendUserIds.append(houseHoldUserMap.get(key));
							} else {
								sendUserIds.append(CommonConstants.COMMA_STRING);
								sendUserIds.append(houseHoldUserMap.get(key));
							}
						}
					}
				}
			}

			//循环countMap 用户信息加入到sendUserIds中
			if (countMap != null && countMap.size() > 0){
				for (String key : countMap.keySet()) {
					if (sendUserIds.length() == 0) {
						sendUserIds.append(key);
					} else {
						sendUserIds.append(CommonConstants.COMMA_STRING);
						sendUserIds.append(key);
					}
				}
			}
			Map<String,SysUser> sendUserMap = new HashMap<>();
			if (sendUserIds.length() > 0) {
				R<SysUsersVo> res = upmsDaprUtils.getInUseUserByIds(sendUserIds.toString());
				if (Common.isNotNull(res) && Common.isNotNull(res.getData()) && Common.isNotNull(res.getData().getUserList())) {
					sendUserMap = res.getData().getUserList();
				}else {
					log.error("社保办理失败通知-获取用户信息失败");
				}
			}
			if (null != sendUserMap){
				String key;
				String mes;
				String houseHoldUserId;
				String[] houseHoldUserIds;
				SysUser user;
				//循环countMap 通过key 从sendUserMap 中取出用户信息，用户信息lockFlag=0 且 wxMessage不为空，则发送微信消息
				if (null != countMap){
					for (Map.Entry<String, StringBuilder> entry : countMap.entrySet()) {
						key = entry.getKey();
						mes = entry.getValue().toString();
						user = sendUserMap.get(key);
						if (user != null &&
								Common.isNotKong(user.getWxMessage()) &&
								CommonConstants.ZERO_STRING.equals(user.getLockFlag())) {
							sendMessageToWx(user.getWxMessage(), mes,"73");
						}
					}
				}
				String value;
				StringBuilder content;
				//循环houseHoldNameMap 通过key 从sendUserMap 中取出用户信息，用户信息lockFlag=0 且 wxMessage不为空，则发送微信消息
				if (null != houseHoldNameMap){
					for (Map.Entry<String, String> entry : houseHoldNameMap.entrySet()) {
						key = entry.getKey();
						value = entry.getValue();
						houseHoldUserId = houseHoldUserMap.get(key);
						//houseHoldUserId 为多个userId 逗号分隔的，所以要拆分出来后循环处理
						houseHoldUserIds = houseHoldUserId.split(CommonConstants.COMMA_STRING);
						for (String userId : houseHoldUserIds) {
							user = sendUserMap.get(userId);
							if (user != null &&
									Common.isNotKong(user.getWxMessage()) &&
									CommonConstants.ZERO_STRING.equals(user.getLockFlag())) {
								content = new StringBuilder();
								content.append("申请人").append(value).append("等");
								Integer count = houseHoldCountMap.get(key);
								if (count != null) {
									content.append(count).append("人状态异常，当前存在社保或公积金派单办理失败。请及时至HRO系统进行处理。");
								} else {
									content.append("状态异常，当前存在社保或公积金派单办理失败。请及时至HRO系统进行处理。");
								}
								sendMessageToWx(user.getWxMessage(), content.toString(),"66");
							}
						}

					}
				}
			}
		}

	}
	//发送企业微信待办
	private void sendMessageToWx(String useruserWx, String content,String number) {
		if (Common.isEmpty(useruserWx) || Common.isEmpty(content)) {
			return;
		}
		StringBuilder sendUser = null;
		if (Common.isNotKong(useruserWx)) {
			sendUser = new StringBuilder(useruserWx);
		}
		if (sendUser != null) {
			RestTemplate restTemplate = new RestTemplate();
			Map<String, Object> requestMap = new HashMap<>();
			Map<String, Object> textcard = new HashMap<>();
			textcard.put("title", "派单办理失败提醒");
			textcard.put("url", String.format(SecurityConstants.WX_GET_MESSAGE_AUTH_URL, wxConfig.getCorpid(), wxConfig.getDomainName() + "/auth/oauth/wxLogin", number+DateUtils.format(new Date(), DateUtil.ISO_DATE_FORMAT) ));
			textcard.put("description", content.toString());
			requestMap.put("touser", sendUser);
			requestMap.put("agentid", wxConfig.getAgentid());
			requestMap.put("msgtype", "textcard");
			requestMap.put("textcard", textcard);
			// 必须加上header说明
			if (!wxConfig.sendTextCard(restTemplate, requestMap)) {
				wxConfig.sendTextCard(restTemplate, requestMap);
			}
		}
	}
	/**
	 * 简单分页查询
	 *
	 * @param tSocialAlertInfo
	 * @return
	 */
	@Override
	public IPage<TSocialAlertInfo> getTSocialAlertInfoPage(Page<TSocialAlertInfo> page, TSocialAlertInfoSearchVo tSocialAlertInfo) {
		return baseMapper.getTSocialAlertInfoPage(page, tSocialAlertInfo);
	}

	/**
	 * 批量导出
	 *
	 * @param searchVo
	 * @return
	 */
	@Override
	public void listExport(HttpServletResponse response, TSocialAlertInfoSearchVo searchVo) {
		return;
	}

	@Override
	public List<TSocialAlertInfo> noPageDiy(TSocialAlertInfoSearchVo searchVo) {
		LambdaQueryWrapper<TSocialAlertInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(searchVo.getReceiveUser())){
			wrapper.eq(TSocialAlertInfo::getReceiveUser, searchVo.getReceiveUser());
		}
		if (Common.isNotNull(idList)) {
			wrapper.in(TSocialAlertInfo::getId, idList);
		}
		if (searchVo.getLimitStart() >= 0 && searchVo.getLimitEnd() > 0) {
			wrapper.last(" limit " + searchVo.getLimitStart() + "," + searchVo.getLimitEnd());
		}
		wrapper.orderByDesc(BaseEntity::getCreateTime);
		return baseMapper.selectList(wrapper);
	}



	private Long noPageCountDiy(TSocialAlertInfoSearchVo searchVo) {
		LambdaQueryWrapper<TSocialAlertInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TSocialAlertInfo::getId, idList);
		}
		return baseMapper.selectCount(wrapper);
	}

	private LambdaQueryWrapper buildQueryWrapper(TSocialAlertInfoSearchVo entity) {
		LambdaQueryWrapper<TSocialAlertInfo> wrapper = Wrappers.lambdaQuery();
		if (ArrayUtil.isNotEmpty(entity.getCreateTimes())) {
			wrapper.ge(TSocialAlertInfo::getCreateTime, entity.getCreateTimes()[0])
					.le(TSocialAlertInfo::getCreateTime,
							entity.getCreateTimes()[1]);
		}
		if (Common.isNotNull(entity.getCreateName())) {
			wrapper.eq(TSocialAlertInfo::getCreateName, entity.getCreateName());
		}
		return wrapper;
	}

	@Override
	public R<List<ErrorMessage>> importDiy(InputStream inputStream) {
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		return R.ok(errorMessageList);
	}

	private void importTSocialAlertInfo(List<TSocialAlertInfoVo> excelVOList, List<ErrorMessage> errorMessageList) {

	}

	/**
	 * 插入excel bad record
	 */
	private void insertExcel(TSocialAlertInfoVo excel) {
		TSocialAlertInfo insert = new TSocialAlertInfo();
		BeanUtil.copyProperties(excel, insert);
		this.save(insert);
	}
}
