package com.sckw.manage.service;

import com.alibaba.fastjson2.JSON;
import com.sckw.core.exception.SystemException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.ClientTypeEnum;
import com.sckw.core.model.enums.CooperateStatusEnum;
import com.sckw.core.model.enums.CooperateTypeEnum;
import com.sckw.core.utils.AsyncThreadUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.utils.UUIDUtils;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.manage.dao.KwmCooperateMapper;
import com.sckw.manage.model.dto.req.CooperateManageQueryReqDto;
import com.sckw.manage.model.dto.res.CooperateManageQueryResDto;
import com.sckw.manage.model.entity.KwmCooperate;
import com.sckw.manage.model.vo.res.CooperateManageQueryResVo;
import com.sckw.manage.model.vo.res.FindListGroupResVo;
import com.sckw.stream.enums.MessageEnum;
import com.sckw.stream.model.SckwMessage;
import com.sckw.stream.model.UserInfo;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.RemoteUserService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author czh
 * @desc 公共
 * @date 2023/7/12
 */
@Service
@Slf4j
public class CommonBusinessService {

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    @Autowired
    private KwmCooperateMapper kwmCooperateMapper;

    @Resource
    private StreamBridge streamBridge;

    @Autowired
    private CommonBusinessService commonBusinessService;


    /**
     * @param keywords 关键字 resDto查询结果集
     * @desc: 是否匹配到关键字
     * @author: czh
     * @date: 2023/7/11
     */
    public boolean matchContacts(String keywords, CooperateManageQueryResDto resDto) {
        if (StringUtils.isNotBlank(resDto.getInviteeContacts()) && resDto.getInviteeContacts().contains(keywords)) {
            return true;
        }

        if (StringUtils.isNotBlank(resDto.getInviterContacts()) && resDto.getInviterContacts().contains(keywords)) {
            return true;
        }

        if (StringUtils.isNotBlank(resDto.getInviterPhone()) && resDto.getInviterPhone().contains(keywords)) {
            return true;
        }

        if (StringUtils.isNotBlank(resDto.getInviteePhone()) && resDto.getInviteePhone().contains(keywords)) {
            return true;
        }

        return false;
    }


    /**
     * @param userIds 用户id
     * @return UserCacheResDto
     * @desc: 查用户信息
     * @author: czh
     * @date: 2023/7/12
     */
    public Map<Long, UserCacheResDto> queryUserCacheMapByIds(List<Long> userIds) {
        return remoteSystemService.queryUserCacheMapByIds(userIds);
    }


    /**
     * @param entIds 企业id
     * @return EntCacheResDto
     * @desc: 查企业信息
     * @author: czh
     * @date: 2023/7/12
     */
    public Map<Long, EntCacheResDto> queryEntCacheMapByIds(List<Long> entIds) {
        return remoteSystemService.queryEntCacheMapByIds(entIds);
    }

    /**
     * @param keys type#value,type#value
     * @return Map
     * @desc: 根据id查字典
     * @author: czh
     * @date: 2023/7/12
     */
    public Map<String, SysDictResDto> queryDictMapByTypeValues(String keys) {
        return remoteSystemService.queryDictMapByTypeValues(keys);
    }

    /**
     * @param type 当前企业的属性
     * @return Integer
     * @desc: 转换成相对的属性
     * @author: czh
     * @date: 2023/7/11
     */
    public Integer changeAttribute(Integer type) {
        if (type == CooperateTypeEnum.SUPPLIER.getCode()) {
            return CooperateTypeEnum.PURCHASER.getCode();
        }

        if (type == CooperateTypeEnum.PURCHASER.getCode()) {
            return CooperateTypeEnum.SUPPLIER.getCode();
        }

        if (type == CooperateTypeEnum.CONSIGN.getCode()) {
            return CooperateTypeEnum.CARRIAGE.getCode();
        }

        if (type == CooperateTypeEnum.CARRIAGE.getCode()) {
            return CooperateTypeEnum.CONSIGN.getCode();
        }

        return Global.NO;
    }


    /**
     * @param reqDto 全量查入参
     * @return CooperateManageQueryResVo
     * @desc: 全量查
     * @author: czh
     * @date: 2023/7/10
     */
    public List<CooperateManageQueryResVo> findList(CooperateManageQueryReqDto reqDto) {
        List<CooperateManageQueryResDto> list = kwmCooperateMapper.findList(reqDto);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        return getCooperateManageQueryResVos(list);
    }

    /**
     * @param list 数据
     * @return CooperateManageQueryResVo
     * @desc: 组装返参
     * @author: czh
     * @date: 2023/8/2
     */
    public List<CooperateManageQueryResVo> getCooperateManageQueryResVos(List<CooperateManageQueryResDto> list) {
        //dubbo接口查用户和企业
        Long entId = LoginUserHolder.getEntId();
        List<String> createByList = list.stream().map(CooperateManageQueryResDto::getCreateByStr).toList();
        List<Long> userIds = new ArrayList<>();
        for (String createByStr : createByList) {
            String[] split = createByStr.split(Global.COMMA);
            for (int n = 0; n < split.length; n ++) {
                userIds.add(Long.valueOf(split[n]));
            }
        }

        List<Long> allEntIds = new ArrayList<>();
        List<Long> targetEntIds = list.stream().map(CooperateManageQueryResDto::getTargetEntId).distinct().toList();
        List<Long> ourEntIds = list.stream().map(CooperateManageQueryResDto::getOurEntId).distinct().toList();
        allEntIds.addAll(targetEntIds);
        allEntIds.addAll(ourEntIds);
        Map<Long, UserCacheResDto> userCacheResDtoMap = remoteSystemService.queryUserCacheMapByIds(userIds);
        List<EntCacheResDto> entCacheResDtos = remoteSystemService.queryEntCacheByIds(allEntIds);
        Map<Long, EntCacheResDto> entMap = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        if (!CollectionUtils.isEmpty(entCacheResDtos)) {
            entMap = entCacheResDtos.stream().collect(Collectors.toMap(EntCacheResDto::getId, Function.identity()));
        }

        List<CooperateManageQueryResVo> result = new ArrayList<>();
        for (CooperateManageQueryResDto cooperateManageQueryResDto : list) {
            Long targetEntId = cooperateManageQueryResDto.getTargetEntId();
            EntCacheResDto entCacheResDto = entMap.get(targetEntId);
            EntCacheResDto entCacheResDto2 = entMap.get(cooperateManageQueryResDto.getOurEntId());

            CooperateManageQueryResVo cooperateManageQueryResVo = new CooperateManageQueryResVo();
            cooperateManageQueryResVo.setId(String.valueOf(cooperateManageQueryResDto.getId()));
            cooperateManageQueryResVo.setRemark(cooperateManageQueryResDto.getRemark());
            cooperateManageQueryResVo.setStatus(cooperateManageQueryResDto.getStatus());
            cooperateManageQueryResVo.setApplyTypeCode(cooperateManageQueryResDto.getApplyTypeCode());
            cooperateManageQueryResVo.setCreateTime(cooperateManageQueryResDto.getCreateTime());
            cooperateManageQueryResVo.setTargetEntName(Objects.nonNull(entCacheResDto) ? entCacheResDto.getFirmName() : "");
            cooperateManageQueryResVo.setTargetEntId(targetEntId);
            cooperateManageQueryResVo.setEntId(cooperateManageQueryResDto.getOurEntId());
            cooperateManageQueryResVo.setEntName(Objects.nonNull(entCacheResDto2) ? entCacheResDto2.getFirmName() : "");
            cooperateManageQueryResVo.setApprovalRemark(cooperateManageQueryResDto.getApprovalRemark());
            cooperateManageQueryResVo.setHead(Objects.nonNull(entCacheResDto) ? entCacheResDto.getHead() : "");
            UserCacheResDto userCacheResDto = userCacheResDtoMap.get(cooperateManageQueryResDto.getCreateBy());
            cooperateManageQueryResVo.setCreateByName(userCacheResDto.getName());

            //我方是发起方
            if (entId.equals(cooperateManageQueryResDto.getEntId())) {
                cooperateManageQueryResVo.setContacts(cooperateManageQueryResDto.getInviteeContacts());
                cooperateManageQueryResVo.setPhone(cooperateManageQueryResDto.getInviteePhone());
                cooperateManageQueryResVo.setContactsId(cooperateManageQueryResDto.getInviteeContactsId());
                cooperateManageQueryResVo.setManager(cooperateManageQueryResDto.getInviterContacts());
                cooperateManageQueryResVo.setManagerPhone(cooperateManageQueryResDto.getInviterPhone());
                cooperateManageQueryResVo.setManagerId(cooperateManageQueryResDto.getInviterContactsId());
                cooperateManageQueryResVo.setCooperateTypes(cooperateManageQueryResDto.getTypes());
            } else {
                cooperateManageQueryResVo.setContacts(cooperateManageQueryResDto.getInviterContacts());
                cooperateManageQueryResVo.setPhone(cooperateManageQueryResDto.getInviterPhone());
                cooperateManageQueryResVo.setContactsId(cooperateManageQueryResDto.getInviterContactsId());
                cooperateManageQueryResVo.setManager(cooperateManageQueryResDto.getInviteeContacts());
                cooperateManageQueryResVo.setManagerPhone(cooperateManageQueryResDto.getInviteePhone());
                cooperateManageQueryResVo.setManagerId(cooperateManageQueryResDto.getInviteeContactsId());
                cooperateManageQueryResVo.setCooperateTypes(commonBusinessService.changeCooperateType(cooperateManageQueryResDto.getTypes()));
            }
            result.add(cooperateManageQueryResVo);
        }
        return result;
    }


    public Integer changeCooperateType(Integer type) {
        if (type.equals(CooperateTypeEnum.SUPPLIER.getCode())) {
            return CooperateTypeEnum.PURCHASER.getCode();
        }

        if (type.equals(CooperateTypeEnum.PURCHASER.getCode())) {
            return CooperateTypeEnum.SUPPLIER.getCode();
        }

        if (type.equals(CooperateTypeEnum.CONSIGN.getCode())) {
            return CooperateTypeEnum.CARRIAGE.getCode();
        }

        if (type.equals(CooperateTypeEnum.CARRIAGE.getCode())) {
            return CooperateTypeEnum.CONSIGN.getCode();
        }
        return null;
    }

    public String changeCooperateType(String types) {
        String str = "";

        if (types.contains(String.valueOf(CooperateTypeEnum.SUPPLIER.getCode()))) {
            str += CooperateTypeEnum.PURCHASER.getCode() + Global.COMMA;
        }

        if (types.contains(String.valueOf(CooperateTypeEnum.PURCHASER.getCode()))) {
            str += CooperateTypeEnum.SUPPLIER.getCode() + Global.COMMA;
        }

        if (types.contains(String.valueOf(CooperateTypeEnum.CONSIGN.getCode()))) {
            str += CooperateTypeEnum.CARRIAGE.getCode() + Global.COMMA;
        }

        if (types.contains(String.valueOf(CooperateTypeEnum.CARRIAGE.getCode()))) {
            str += CooperateTypeEnum.CONSIGN.getCode() + Global.COMMA;
        }

        return str.substring(0, str.length() - 1);
    }

    /**
     * @return FindListGroupResVo
     * @desc: 初始化分组返参
     * @author: czh
     * @date: 2023/7/17
     */
    public List<FindListGroupResVo> init() {
        CooperateStatusEnum[] values = CooperateStatusEnum.values();
        List<FindListGroupResVo> result = new ArrayList<>();
        FindListGroupResVo total = new FindListGroupResVo();
        total.setCount(0);
        result.add(total);

        for (CooperateStatusEnum value : values) {
            FindListGroupResVo findListGroupResVo = new FindListGroupResVo();
            findListGroupResVo.setStatus(value.getCode());
            findListGroupResVo.setStatusName(value.getName());
            findListGroupResVo.setCount(0);
            result.add(findListGroupResVo);
        }
        return result;
    }


    /**
     * @param result 返回分组信息  list 数据集
     * @desc: 填充分组数据
     * @author: czh
     * @date: 2023/7/17
     */
    public void fillGroup(List<FindListGroupResVo> result, List<CooperateManageQueryResVo> list) {
        //按状态分组
        Map<Integer, List<CooperateManageQueryResVo>> collect = list.stream().collect(Collectors.groupingBy(CooperateManageQueryResVo::getStatus));
        for (FindListGroupResVo findListGroupResVo : result) {
            List<CooperateManageQueryResVo> cooperateManageQueryResVos = collect.get(findListGroupResVo.getStatus());
            if (CollectionUtils.isNotEmpty(cooperateManageQueryResVos)) {
                findListGroupResVo.setCount(cooperateManageQueryResVos.size());
            }
        }

        //给汇总项求和
        result.get(0).setCount(list.size());
    }


    /**
     * @param userId 用户id id主键
     * @desc: 绑定客户经理
     * @author: czh
     * @date: 2023/7/24
     */
    public void bingManager(Long userId, Long id) {
        KwmCooperate kwmCooperate = kwmCooperateMapper.selectById(id);
        if (Objects.isNull(kwmCooperate)) {
            throw new SystemException(HttpStatus.QUERY_FAIL_CODE, HttpStatus.COOPERATE_NOT_EXISTS);
        }

        UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(userId);
        if (Objects.isNull(userCacheResDto)) {
            throw new SystemException(HttpStatus.QUERY_FAIL_CODE, HttpStatus.ACCOUNT_NOT_EXISTS);
        }

        Long entId = kwmCooperate.getEntId();
        Long currentEntId = LoginUserHolder.getEntId();
        //不相等则不是该合作的创建人，应该修改受邀请人信息
        if (entId.compareTo(currentEntId) != 0) {
            kwmCooperate.setInviteeContactsId(userCacheResDto.getId());
            kwmCooperate.setInviteeContacts(userCacheResDto.getName());
            kwmCooperate.setInviteePhone(userCacheResDto.getPhone());
        } else {
            kwmCooperate.setInviterContactsId(userCacheResDto.getId());
            kwmCooperate.setInviterContacts(userCacheResDto.getName());
            kwmCooperate.setInviterPhone(userCacheResDto.getPhone());
        }
        kwmCooperate.setUpdateTime(new Date());
        kwmCooperate.setUpdateBy(LoginUserHolder.getUserId());
        if (kwmCooperateMapper.updateById(kwmCooperate) <= 0) {
            throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.UPDATE_FAIL);
        }
    }


    public void sendSystemMessage(List<UserInfo> userInfos, MessageEnum messageEnum, Map<String, Object> map, String msgUrl, String appMsgUrl) {
        SckwMessage msg = new SckwMessage();
        Map<String, String> msgUrls = new HashMap<>(Global.NUMERICAL_FOUR);
        msgUrls.put(ClientTypeEnum.pc.getValue(), msgUrl);
        if (StringUtils.isNotBlank(appMsgUrl)) {
            msgUrls.put(ClientTypeEnum.app.getValue(), appMsgUrl);
        }

        msg.setRequestId(UUIDUtils.get32UUID())
                .setMessageEnum(messageEnum)
                .setParams(map)
                .setMsgUrls(msgUrls)
                .setUserInfos(userInfos)
                .setCreateBy(LoginUserHolder.getUserId());
        AsyncThreadUtils.submit(new AsyncProcess(msg, streamBridge));
    }


    static class AsyncProcess implements Runnable {

        private SckwMessage sckwMessage;

        private StreamBridge streamBridge;

        AsyncProcess(SckwMessage sckwMessage, StreamBridge streamBridge) {
            this.sckwMessage = sckwMessage;
            this.streamBridge = streamBridge;
        }

        @Override
        public void run() {
            streamBridge.send("sckw-message", JSON.toJSONString(sckwMessage));
        }
    }
}
