package com.gic.haoban.manage.service.service.contact.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.gic.api.base.commons.BasePageInfo;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.haoban.manage.api.dto.contact.ContactFollowDTO;
import com.gic.haoban.manage.api.dto.contact.ContactFollowGoodsDTO;
import com.gic.haoban.manage.api.enums.contact.ContactFollowTypeEnum;
import com.gic.haoban.manage.api.qdto.contact.ContactFollowQDTO;
import com.gic.haoban.manage.api.qdto.contact.ContactFollowSearchQDTO;
import com.gic.haoban.manage.api.qdto.contact.ContactLogQDTO;
import com.gic.haoban.manage.service.dao.mapper.contact.TabContactFollowMapper;
import com.gic.haoban.manage.service.entity.contact.TabContactFollow;
import com.gic.haoban.manage.service.service.contact.ContactFollowService;
import com.gic.mq.sdk.GicMQClient;
import com.gic.store.goods.service.StoreGoodsService;
import com.gic.store.goods.vo.StoreGoodsVO;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service("contactFollowService")
public class ContactFollowServiceImpl implements ContactFollowService {

    private static final Logger logger = LogManager.getLogger(ContactFollowService.class);

    @Autowired
    private TabContactFollowMapper contactFollowMapper;
    @Autowired
    private StoreGoodsService storeGoodsService;
    @Autowired
    private ClerkService clerkService;

    @Override
    public void saveFollow(ContactFollowQDTO qdto) {
        saveBatchFollow(Lists.newArrayList(qdto));
    }

    @Override
    public void saveBatchFollow(List<ContactFollowQDTO> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        Set<String> clerkSet = list.stream().map(ContactFollowQDTO::getClerkId).collect(Collectors.toSet());
        List<ClerkDTO> clerks = clerkService.getClerkByClerkIds(clerkSet);
        if (CollectionUtils.isEmpty(clerks)) {
            return;
        }
        Map<String, ClerkDTO> clerkMap = clerks.stream().collect(Collectors.toMap(ClerkDTO::getClerkId, Function.identity(), (v1, v2) -> v1));
        List<TabContactFollow> followList = list.stream().map(follow -> {
            TabContactFollow contactFollow = EntityUtil.changeEntityNew(TabContactFollow.class, follow);
            ClerkDTO clerkDTO = clerkMap.get(follow.getClerkId());
            if (clerkDTO == null) {
                return null;
            }
            contactFollow.setClerkCode(clerkDTO.getClerkCode());
            contactFollow.setFollowId(UniqueIdUtils.uniqueLong());
            if (CollectionUtils.isNotEmpty(follow.getFollowMaterialList())) {
                contactFollow.setFollowMaterial(JSON.toJSONString(follow.getFollowMaterialList()));
            }
            if (CollectionUtils.isNotEmpty(follow.getGoodsInfoList())) {
                contactFollow.setGoodsInfo(JSON.toJSONString(follow.getGoodsInfoList()));
            }
            // 兼容不传followType的老版本
            Integer followType = contactFollow.getFollowType();
            if (followType == null) {
                ContactFollowTypeEnum followTypeEnum = ContactFollowTypeEnum.fromTextMatch(contactFollow.getFollowRemark());
                followType = Optional.ofNullable(followTypeEnum).map(ContactFollowTypeEnum::getCode).orElse(ContactFollowTypeEnum.CONTACT.getCode());
                contactFollow.setFollowType(followType);
            }
            return contactFollow;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        contactFollowMapper.insertBatch(followList);
        // 部分跟进发送自动建联
        autoContactSend(followList);
    }

    private static void autoContactSend(List<TabContactFollow> followList) {
        // 自动建联
        Integer followType = followList.get(0).getFollowType();
        Integer contactAutoType = ContactFollowTypeEnum.fromCode(followType).getContactAutoType();
        if (contactAutoType != null) {
            List<String> message = followList.stream().map(x -> {
                ContactLogQDTO contactLogQDTO = new ContactLogQDTO();
                contactLogQDTO.setMemberId(x.getMemberId());
                contactLogQDTO.setClerkId(x.getClerkId());
                contactLogQDTO.setEnterpriseId(x.getEnterpriseId());
                contactLogQDTO.setContactAutoType(contactAutoType);
                return JSON.toJSONString(contactLogQDTO);
            }).collect(Collectors.toList());
            String routerName = "autoContactLogForMQ";
            try {
                GicMQClient clientInstance = GICMQClientUtil.getClientInstance();
                clientInstance.sendBatchMessages(routerName, message);
            } catch (Exception e) {
                logger.error("发送错误！路由规则名称：" + routerName + ",message:" + message,e);
            }
            message.clear();
        }
    }

    @Override
    public Page<ContactFollowDTO> pageFollow(String enterpriseId, ContactFollowSearchQDTO searchQDTO, BasePageInfo pageInfo) {
        PageHelper.startPage(pageInfo);
        List<TabContactFollow> list = contactFollowMapper.pageFollow(enterpriseId, searchQDTO);
        Page<ContactFollowDTO> page = PageHelperUtils.changePageHelperToCurrentPage(list,ContactFollowDTO.class);
        List<ContactFollowDTO> pageList = convertExtInfo(list);
        page.setResult(pageList);
        return page;
    }

    @Override
    public Map<String, ContactFollowDTO> mapMemberLastFollow(String enterpriseId, String clerkId,List<String> memberIdList) {
        if (CollectionUtils.isEmpty(memberIdList)) {
            return new HashMap<>();
        }
        List<TabContactFollow> list = contactFollowMapper.lastFollowByMemberId(enterpriseId, clerkId, memberIdList);
        List<ContactFollowDTO> followDTOList = convertExtInfo(list);
        Map<String, ContactFollowDTO> map = followDTOList.stream().collect(Collectors.toMap(ContactFollowDTO::getMemberId, v -> v,
                (v1, v2) -> v1));
        return map;
    }

    private List<ContactFollowDTO> convertExtInfo(List<TabContactFollow> list) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        Map<String, StoreGoodsVO> goodsMap = new HashMap<>();
        Set<String> goodsIdSet = list.stream().map(TabContactFollow::getGoodsInfo).filter(StringUtils::isNotBlank)
                .flatMap(x -> JSONArray.parseArray(x,String.class).stream()).collect(Collectors.toSet());
        // 组装商品信息
        if (CollectionUtils.isNotEmpty(goodsIdSet)) {
            ServiceResponse<List<StoreGoodsVO>> response = storeGoodsService.listByGoodsIds(Lists.newArrayList(goodsIdSet));
            if (response.isSuccess() && CollectionUtils.isNotEmpty(response.getResult())) {
                goodsMap = response.getResult().stream().collect(Collectors.toMap(StoreGoodsVO::getGoodsId, Function.identity(), (v1, v2) -> v1));
            }
        }
        Map<String, StoreGoodsVO> finalGoodsMap = goodsMap;
        List<ContactFollowDTO> pageList = list.stream().map(follow -> {
            ContactFollowDTO contactFollowDTO = EntityUtil.changeEntityNew(ContactFollowDTO.class, follow);
            String followMaterial = follow.getFollowMaterial();
            if (StringUtils.isNotBlank(followMaterial)) {
                contactFollowDTO.setFollowMaterialList(JSONArray.parseArray(followMaterial, String.class));
            }
            String goodsInfo = follow.getGoodsInfo();
            if (StringUtils.isNotBlank(goodsInfo)) {
                List<String> goodsIdList = JSONArray.parseArray(goodsInfo, String.class);
                List<ContactFollowGoodsDTO> goodsInfoList = goodsIdList.stream().map(goodsId -> {
                    StoreGoodsVO storeGoodsVO = finalGoodsMap.get(goodsId);
                    if (storeGoodsVO == null) {
                        return null;
                    }
                    return EntityUtil.changeEntityNew(ContactFollowGoodsDTO.class, storeGoodsVO);
                }).filter(Objects::nonNull).collect(Collectors.toList());
                contactFollowDTO.setGoodsInfoList(goodsInfoList);
            }
            return contactFollowDTO;
        }).collect(Collectors.toList());
        return pageList;
    }

}
