package com.cyksj.service.corp.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.Jsons;
import com.cyksj.mapper.corp.CorpFollowActiveCodeMapper;
import com.cyksj.mapper.corp.CorpTagGroupMapper;
import com.cyksj.mapper.corp.CorpTagMapper;
import com.cyksj.model.entity.CmsUser;
import com.cyksj.model.entity.CorpFollowActiveCode;
import com.cyksj.model.entity.CorpTag;
import com.cyksj.model.entity.CorpTagGroup;
import com.cyksj.model.request.corp.Attachments;
import com.cyksj.redis.RedisService;
import com.cyksj.service.corp.CorpFollowDynamicConfigService;
import com.cyksj.service.corp.CorpFollowService;
import com.cyksj.service.corp.WxCorpOps;
import com.cyksj.service.mange.cms.CmsUserManager;
import com.cyksj.service.sys.SysCorpServiceRelateService;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * 项目名: yhlxj
 * 文件名: CorpFollowServiceImpl
 * 创建者: JavaZou
 * 创建时间:2023/10/9 16:27
 */
@Service
@RequiredArgsConstructor
public class CorpFollowServiceImpl implements CorpFollowService {
	private final CorpFollowActiveCodeMapper corpFollowActiveCodeMapper;

	private final CmsUserManager cmsUserManager;

	private final CorpFollowDynamicConfigService corpFollowDynamicConfigService;

	private final WxCorpOps wxCorpOps;

	private final CorpTagMapper corpTagMapper;

	private final CorpTagGroupMapper corpTagGroupMapper;

	private final RedisService redisService;

	private final SysCorpServiceRelateService sysCorpServiceRelateService;

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void postActiveCode(Long adminId, CorpFollowActiveCode activeCode) throws Exception {
		CmsUser cmsUser = cmsUserManager.getUser(adminId);
		if (cmsUser != null) {
			activeCode.setOperator(cmsUser.getNickname());
		}
		Boolean isDuty = Optional.ofNullable(activeCode.getIsDuty()).orElse(false);
		List<Integer> userIndxList = activeCode.getUserIndxList();

		if (CollUtil.isEmpty(userIndxList)) {
			throw BusinessRuntimeException.getInstance("请选择对应客服");
		}
		activeCode.setFollowStr(Jsons.toJson(userIndxList));
		List<String> followStrList = sysCorpServiceRelateService.getFollowIdsByRelateIds(userIndxList);
		activeCode.setMarkTag(activeCode.getMarkTag().trim());
		String text = activeCode.getText();
		if (StrUtil.isNotBlank(text) && text.length() > 4000) {
			throw BusinessRuntimeException.getInstance("欢迎语内容过长");
		}
		//附件
		List<Attachments> attachments = activeCode.getAttachments();
		if (CollUtil.isNotEmpty(attachments)) {
			activeCode.setAttachmentsStr(Jsons.toJson(attachments));
		}
		//是否值班
		String codeStr;
		try {
			corpFollowActiveCodeMapper.insert(activeCode);
		} catch (DuplicateKeyException e) {
			throw BusinessRuntimeException.getInstance("存在相同的标记标签");
		}
		if (!isDuty) {
			//生成一个活码 一个客服或多个客服
			codeStr = corpFollowDynamicConfigService.createCorpFollowActiveCode(followStrList, userIndxList, Constant.AC_CODE_KEY + activeCode.getId(), isDuty);
		} else {
			codeStr = corpFollowDynamicConfigService.createCorpFollowActiveCode(followStrList, userIndxList, Constant.AC_CODE_KEY + activeCode.getId(), isDuty);
		}
		activeCode.setCodeStr(codeStr);
		corpFollowActiveCodeMapper.updateById(activeCode);
	}

	@Override
	public void upActiveCode(CorpFollowActiveCode activeCode) throws Exception {
		Long activeCodeId = activeCode.getId();
		if (activeCodeId == null) {
			throw BusinessRuntimeException.getInstance("请编辑对应的数据");
		}
		CorpFollowActiveCode dbActiveCode = corpFollowActiveCodeMapper.selectById(activeCodeId);
		if (dbActiveCode == null || !dbActiveCode.getDeleted()) {
			throw BusinessRuntimeException.getInstance("对应的数据已不存在");
		}
		String db_followStr = dbActiveCode.getFollowStr();
		List<Integer> upUserIndxList = activeCode.getUserIndxList();
		if (CollUtil.isEmpty(upUserIndxList)) {
			throw BusinessRuntimeException.getInstance("请选择对应客服");
		}
		activeCode.setFollowStr(Jsons.toJson(upUserIndxList));
		List<String> up_followStrList = sysCorpServiceRelateService.getFollowIdsByRelateIds(upUserIndxList);
		if (StrUtil.isEmpty(activeCode.getMarkTag())) {
			throw BusinessRuntimeException.getInstance("请输入标签");
		}
		List<Integer> db_followIds = Jsons.parseList(db_followStr, Integer.class);
		Boolean isReCreateAcCode = false;
		Boolean isUpdateAcCode = false;
		if (db_followIds.size() != upUserIndxList.size()) {
			isReCreateAcCode = true;
		}
		if (!isReCreateAcCode) {
			for (Integer upFollowId : upUserIndxList) {
				if (!db_followIds.contains(upFollowId)) {
					isReCreateAcCode = true;
					break;
				}
			}
		}
		Boolean db_isDuty = dbActiveCode.getIsDuty();
		Boolean up_isDuty = activeCode.getIsDuty();
		if (db_isDuty != up_isDuty) {
			isReCreateAcCode = true;
		}
		activeCode.setMarkTag(activeCode.getMarkTag().trim());
		if (!dbActiveCode.getMarkTag().equals(activeCode.getMarkTag())) {
			isUpdateAcCode = true;
		}
		List<Attachments> attachments = activeCode.getAttachments();
		if (CollUtil.isEmpty(attachments)) {
			activeCode.setAttachmentsStr(null);
		} else {
			String attachmentsStr = Jsons.toJson(attachments);
			activeCode.setAttachmentsStr(attachmentsStr);
		}

		//重新构建活码配置
		if (isReCreateAcCode) {
			String code_str = corpFollowDynamicConfigService.createCorpFollowActiveCode(up_followStrList, upUserIndxList, Constant.AC_CODE_KEY + activeCode.getId(), up_isDuty);
			activeCode.setCodeStr(code_str);
			Set<String> keys = redisService.keys(RedisService.key.CORP_FOLLOW_ACTIVE_CODE_KEY.getNameFormat(activeCode.getId(), "*"));
			redisService.del(keys.toArray(String[]::new));
		} else if (isUpdateAcCode) {
			corpFollowDynamicConfigService.updateCorpFollowActiveCode(dbActiveCode.getMarkTag(), activeCode.getMarkTag());
		}
		if (activeCode.getMsgId() == null) {
			activeCode.setMsgId(0l);
		}
		corpFollowActiveCodeMapper.updateById(activeCode);
	}

	@Override
	public void deleteActiveCodeById(Long id) throws Exception {
		CorpFollowActiveCode corpFollowActiveCode = corpFollowActiveCodeMapper.selectById(id);
		if (corpFollowActiveCode == null) {
			return;
		}
		corpFollowActiveCode.setDeleted(false);
		corpFollowActiveCodeMapper.updateById(corpFollowActiveCode);

		CorpTag corpTag = corpTagMapper.selectOne(Wrappers.lambdaQuery(CorpTag.class)
				.eq(CorpTag::getName, corpFollowActiveCode.getMarkTag()).last("limit 1"));
		if (corpTag != null) {
			try {
				wxCorpOps.delCorpTag(new String[]{corpTag.getTagId()}, null);
			} catch (Exception e) {
			}
			//删除标签
			corpTagMapper.deleteById(corpTag.getId());
			//删除标签组
			corpTagGroupMapper.delete(Wrappers.lambdaQuery(CorpTagGroup.class)
					.eq(CorpTagGroup::getGroupId, corpTag.getGroupId()));
		}
	}
}
