package com.linkwechat.wecom.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.linkwechat.common.constant.Constants;
import com.linkwechat.common.constant.WeConstans;
import com.linkwechat.common.utils.DateUtils;
import com.linkwechat.common.utils.SecurityUtils;
import com.linkwechat.common.utils.StringUtils;
import com.linkwechat.common.utils.Threads;
import com.linkwechat.common.utils.bean.BeanUtils;
import com.linkwechat.wecom.client.WeCustomerClient;
import com.linkwechat.wecom.client.WeUserClient;
import com.linkwechat.wecom.domain.*;
import com.linkwechat.wecom.domain.dto.AllocateWeCustomerDto;
import com.linkwechat.wecom.domain.dto.WeWelcomeMsg;
import com.linkwechat.wecom.domain.dto.customer.CutomerTagEdit;
import com.linkwechat.wecom.domain.dto.customer.ExternalUserDetail;
import com.linkwechat.wecom.domain.dto.customer.ExternalUserList;
import com.linkwechat.wecom.domain.dto.customer.FollowUserList;
import com.linkwechat.wecom.domain.vo.WeLeaveUserInfoAllocateVo;
import com.linkwechat.wecom.domain.vo.WeMakeCustomerTag;
import com.linkwechat.wecom.mapper.WeCustomerMapper;
import com.linkwechat.wecom.service.*;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 企业微信客户Service业务层处理
 *
 * @author ruoyi
 * @date 2020-09-13
 */
@Service
public class WeCustomerServiceImpl extends ServiceImpl<WeCustomerMapper, WeCustomer> implements IWeCustomerService {
    @Autowired
    private WeCustomerMapper weCustomerMapper;


    @Autowired
    private WeCustomerClient weCustomerClient;


    @Autowired
    private IWeFlowerCustomerRelService iWeFlowerCustomerRelService;


    @Autowired
    private IWeTagGroupService iWeTagGroupService;


    @Autowired
    private IWeFlowerCustomerTagRelService iWeFlowerCustomerTagRelService;


    @Autowired
    private IWeAllocateCustomerService iWeAllocateCustomerService;


    @Autowired
    private WeUserClient weUserClient;



    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(WeCustomer weCustomer) {
        return saveOrUpdate(weCustomer,new LambdaQueryWrapper<WeCustomer>()
                .eq(WeCustomer::getExternalUserid,weCustomer.getExternalUserid())
                .eq(WeCustomer::getStatus,0));
    }

    /**
     * 查询id企业微信客户
     *
     * @param id
     * @return 企业微信客户
     */
    @Override
    public WeCustomer selectWeCustomerById(Long id) {
        return weCustomerMapper.selectWeCustomerById(id);
    }

    /**
     * 查询eid企业微信客户
     *
     * @param externalUserId 企业微信客户id
     * @return 企业微信客户
     */
    @Override
    public WeCustomer selectWeCustomerByEid(String externalUserId) {
        return weCustomerMapper.selectWeCustomerByEid(externalUserId);
    }

    /**
     * 查询企业微信客户列表
     *
     * @param weCustomer 企业微信客户
     * @return 企业微信客户
     */
    @Override
    public List<WeCustomer> selectWeCustomerList(WeCustomer weCustomer) {
        //当前登录用户为企业用户
        if (Constants.USER_TYPE_WECOME
                .equals(SecurityUtils.getLoginUser().getUser().getUserType())) {
            weCustomer.setUserIds((SecurityUtils.getLoginUser().getUser().getWeUserId()));
        }
        return weCustomerMapper.selectWeCustomerList(weCustomer);
    }


    /**
     * 客户同步接口
     *
     * @return
     */
    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void synchWeCustomer() {
        FollowUserList followUserList = weCustomerClient.getFollowUserList();
        if (WeConstans.WE_SUCCESS_CODE.equals(followUserList.getErrcode())
                && ArrayUtil.isNotEmpty(followUserList.getFollow_user())) {
            SecurityContext securityContext = SecurityContextHolder.getContext();
            Arrays.asList(followUserList.getFollow_user()).forEach(k -> {
                try {
                    Threads.SINGLE_THREAD_POOL.execute(() -> {
                        SecurityContextHolder.setContext(securityContext);
                        weFlowerCustomerHandle(k);
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }

    /**
     * 客户同步业务处理
     *
     * @param userId 开通权限的企业成员id
     */
    private void weFlowerCustomerHandle(String userId) {
        //当前登录人的企业id
        List<ExternalUserDetail> list = new ArrayList<>(16);
        getByUser(userId, null, list);
        List<WeCustomer> customerList = new ArrayList<>(16);
        list.forEach(userDetail -> {
            //客户入库
            WeCustomer weCustomer = new WeCustomer();
            BeanUtils.copyPropertiesignoreOther(userDetail.getExternalContact(), weCustomer);
            weCustomer.setCreateTime(new Date());
            weCustomer.setUpdateTime(new Date());
            weCustomer.setCreateBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername());
            weCustomer.setUpdateBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername());
            customerList.add(weCustomer);

            //客户与通讯录客户关系
            List<WeFlowerCustomerTagRel> weFlowerCustomerTagRels = new ArrayList<>();
            List<WeFlowerCustomerRel> weFlowerCustomerRels = new ArrayList<>();
            Optional.ofNullable(userDetail.getFollowInfo()).ifPresent(followInfo -> {
                weFlowerCustomerRels.add(WeFlowerCustomerRel.builder()
                        .userId(userId)
                        .externalUserid(weCustomer.getExternalUserid())
                        .description(followInfo.getDescription())
                        .remarkCorpName(followInfo.getRemarkCompany())
                        .remarkMobiles(String.join(",", followInfo.getRemarkMobiles()))
                        .operUserId(followInfo.getOperUserId())
                        .addWay(followInfo.getAddWay())
                        .addTime(new Date(followInfo.getCreateTime() * 1000L))
                        .createTime(new Date())
                        .updateTime(new Date())
                        .createBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername())
                        .updateBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername())
                        .build());

                if (CollectionUtil.isNotEmpty(followInfo.getTagId())) {
                    followInfo.getTagId().forEach(tagId -> {
                        weFlowerCustomerTagRels.add(
                                WeFlowerCustomerTagRel.builder()
                                        .userId(userId)
                                        .externalUserid(weCustomer.getExternalUserid())
                                        .tagId(tagId)
                                        .build());
                    });
                }
            });

            if (CollectionUtil.isNotEmpty(customerList)) {
                this.weCustomerMapper.insertBatch(customerList);
            }

            if (CollectionUtil.isNotEmpty(weFlowerCustomerRels)) {
                iWeFlowerCustomerRelService.insertBatch(weFlowerCustomerRels);
            }
            if (CollectionUtil.isNotEmpty(weFlowerCustomerTagRels)) {
                iWeFlowerCustomerTagRelService.insertBatch(weFlowerCustomerTagRels);
            }
        });
    }

    /**
     * 批量获取客户详情
     *
     * @param userId     企业成员的userid
     * @param nextCursor 用于分页查询的游标
     * @param list       返回结果
     */
    private void getByUser(String userId, String nextCursor, List<ExternalUserDetail> list) {
        Map<String, Object> query = new HashMap<>(16);
        query.put(WeConstans.USER_ID, userId);
        query.put(WeConstans.CURSOR, nextCursor);
        ExternalUserList externalUserList = weCustomerClient.getByUser(query);
        if (WeConstans.WE_SUCCESS_CODE.equals(externalUserList.getErrcode())
                || WeConstans.NOT_EXIST_CONTACT.equals(externalUserList.getErrcode())
                && ArrayUtil.isNotEmpty(externalUserList.getExternal_contact_list())) {
            list.addAll(externalUserList.getExternal_contact_list());
            if (StringUtils.isNotEmpty(externalUserList.getNext_cursor())) {
                getByUser(userId, externalUserList.getNext_cursor(), list);
            }
        }
    }


    /**
     * 分配离职员工客户
     *
     * @param weLeaveUserInfoAllocateVo
     */
    @Override
    @Transactional
    public void allocateWeCustomer(WeLeaveUserInfoAllocateVo weLeaveUserInfoAllocateVo) {

        List<WeFlowerCustomerRel> weFlowerCustomerRels = iWeFlowerCustomerRelService.list(new LambdaQueryWrapper<WeFlowerCustomerRel>()
                .eq(WeFlowerCustomerRel::getUserId, weLeaveUserInfoAllocateVo.getHandoverUserid()));

        if (CollectionUtil.isNotEmpty(weFlowerCustomerRels)) {

            List<WeAllocateCustomer> weAllocateCustomers = new ArrayList<>();
            weFlowerCustomerRels.stream().forEach(k -> {
                k.setUserId(weLeaveUserInfoAllocateVo.getTakeoverUserid());
                weAllocateCustomers.add(
                        WeAllocateCustomer.builder()
                                .allocateTime(new Date())
                                .externalUserid(k.getExternalUserid())
                                .handoverUserid(weLeaveUserInfoAllocateVo.getHandoverUserid())
                                .takeoverUserid(weLeaveUserInfoAllocateVo.getTakeoverUserid())
                                .build()
                );
            });

            //更新当前接手用户的id
            iWeFlowerCustomerRelService.saveOrUpdateBatch(weFlowerCustomerRels);


            if (CollectionUtil.isNotEmpty(weAllocateCustomers)) {

                //记录分配历史
                if (iWeAllocateCustomerService.saveBatch(weAllocateCustomers)) {
                    //同步企业微信端
                    weAllocateCustomers.stream().forEach(v -> {
                        weUserClient.allocateCustomer(AllocateWeCustomerDto.builder()
                                .external_userid(v.getExternalUserid())
                                .handover_userid(v.getHandoverUserid())
                                .takeover_userid(v.getTakeoverUserid())
                                .build());
                    });

                }

            }


        }

    }


    /**
     * 客户打标签
     *
     * @param weMakeCustomerTag
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void makeLabel(WeMakeCustomerTag weMakeCustomerTag) {
        List<WeTag> addTag = weMakeCustomerTag.getAddTag();
        if(CollectionUtil.isNotEmpty(addTag)){
            List<WeFlowerCustomerTagRel> weFlowerCustomerTagRels = addTag.stream().map(tag -> WeFlowerCustomerTagRel.builder()
                    .externalUserid(weMakeCustomerTag.getExternalUserid())
                    .tagId(tag.getTagId()).build()).collect(Collectors.toList());
            iWeFlowerCustomerTagRelService.insertBatch(weFlowerCustomerTagRels);
        }
        removeLabel(weMakeCustomerTag);
    }


    /**
     * 移除客户标签
     *
     * @param weMakeCustomerTag
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeLabel(WeMakeCustomerTag weMakeCustomerTag) {
        List<WeTag> deleteTag = weMakeCustomerTag.getDeleteTag();
        if(CollectionUtil.isNotEmpty(deleteTag)){
            LambdaQueryWrapper<WeFlowerCustomerTagRel> wrapper = new LambdaQueryWrapper<WeFlowerCustomerTagRel>()
                    .eq(WeFlowerCustomerTagRel::getExternalUserid, weMakeCustomerTag.getExternalUserid())
                    .in(WeFlowerCustomerTagRel::getTagId, deleteTag.stream().map(WeTag::getTagId).collect(Collectors.toList()));
            iWeFlowerCustomerTagRelService.remove(wrapper);
        }
    }


    /**
     * 根据员工ID获取客户
     *
     * @param userId
     * @return
     */
    @Override
    public List<WeCustomer> getCustomersByUserId(String userId) {
        if (StringUtils.isEmpty(userId) && Constants.USER_TYPE_WECOME.equals(SecurityUtils.getLoginUser().getUser().getUserType())) {
            userId = SecurityUtils.getLoginUser().getUser().getWeUserId();
        }
        return this.baseMapper.getCustomersByUserId(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void getCustomersInfoAndSynchWeCustomer(String externalUserid) {
        //获取指定客户的详情
        ExternalUserDetail externalUserDetail = weCustomerClient.get(externalUserid);
        List<WeCustomer> customerList = new ArrayList<>(16);
        if (WeConstans.WE_SUCCESS_CODE.equals(externalUserDetail.getErrcode())) {
            //客户入库
            WeCustomer weCustomer = new WeCustomer();
            BeanUtils.copyPropertiesASM(externalUserDetail.getExternalContact(), weCustomer);
            weCustomer.setCreateTime(new Date());
            weCustomer.setUpdateTime(new Date());
            weCustomer.setCreateBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername());
            weCustomer.setUpdateBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername());
            customerList.add(weCustomer);

            //客户与通讯录客户关系
            List<WeFlowerCustomerTagRel> weFlowerCustomerTagRels = new ArrayList<>();
            List<WeFlowerCustomerRel> weFlowerCustomerRels = new ArrayList<>();
            externalUserDetail.getFollowUser().forEach(followUser -> {
                weFlowerCustomerRels.add(WeFlowerCustomerRel.builder()
                        .userId(followUser.getUserid())
                        .externalUserid(weCustomer.getExternalUserid())
                        .description(followUser.getDescription())
                        .remarkCorpName(followUser.getRemarkCorpName())
                        .remarkMobiles(String.join(",", followUser.getRemarkMobiles()))
                        .operUserId(followUser.getUserid())
                        .addWay(followUser.getAddWay())
                        .state(followUser.getState())
                        .addTime(new Date(followUser.getCreateTime() * 1000L))
                        .createTime(new Date())
                        .updateTime(new Date())
                        .createBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername())
                        .updateBy(StringUtils.isEmpty(SecurityUtils.getUsername())?"0":SecurityUtils.getUsername())
                        .build());

                if (CollectionUtil.isNotEmpty(followUser.getTags())) {
                    followUser.getTags().forEach(tag -> {
                        weFlowerCustomerTagRels.add(
                                WeFlowerCustomerTagRel.builder()
                                        .userId(followUser.getUserid())
                                        .externalUserid(externalUserid)
                                        .tagId(tag.getTag_id())
                                        .build());
                    });
                }
            });

            if (CollectionUtil.isNotEmpty(customerList)) {
                this.weCustomerMapper.insertBatch(customerList);
            }

            if (CollectionUtil.isNotEmpty(weFlowerCustomerRels)) {
                iWeFlowerCustomerRelService.insertBatch(weFlowerCustomerRels);
            }
            if (CollectionUtil.isNotEmpty(weFlowerCustomerTagRels)) {
                iWeFlowerCustomerTagRelService.insertBatch(weFlowerCustomerTagRels);
            }
        }


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCustomersByEid(String externalUserid) {
        this.removeById(externalUserid);
    }

    @Override
    public void sendWelcomeMsg(WeWelcomeMsg weWelcomeMsg) {
        weCustomerClient.sendWelcomeMsg(weWelcomeMsg);
    }

    @Override
    public boolean updateCustomerChatStatus(String externalUserId) {
        WeCustomer weCustomer = new WeCustomer();
        weCustomer.setExternalUserid(externalUserId);
        weCustomer.setIsOpenChat(1);
        return saveOrUpdate(weCustomer);
    }

    @Override
    public List<WeCustomer> getCustomerByTagIds(List<String> tagIds) {
        WeCustomer weCustomer = new WeCustomer();
        weCustomer.setTagIds(String.join(",", tagIds));
        return weCustomerMapper.selectWeCustomerList(weCustomer);
    }


    @Override
    public WeCustomerPortrait findCustomerByOperUseridAndCustomerId(String externalUserid, String userid) throws Exception {
        WeCustomerPortrait weCustomerPortrait
                = weCustomerMapper.findCustomerByOperUseridAndCustomerId(externalUserid, userid);

        if (null != weCustomerPortrait) {

            if (weCustomerPortrait.getBirthday() != null) {
                weCustomerPortrait.setAge(DateUtils.getAge(weCustomerPortrait.getBirthday()));
            }

            //获取当前客户拥有得标签
            weCustomerPortrait.setWeTagGroupList(iWeTagGroupService.findCustomerTag(externalUserid,userid, 2));

            //客户社交关系
            weCustomerPortrait.setSocialConn(
                    this.baseMapper.countSocialConn(externalUserid, userid)
            );
        } else {
            weCustomerPortrait = new WeCustomerPortrait();
        }


        return weCustomerPortrait;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWeCustomerPortrait(WeCustomerPortrait weCustomerPortrait) {
        WeCustomer weCustomer
                = WeCustomer.builder().build();
        BeanUtils.copyBeanProp(weCustomer, weCustomerPortrait);
        //更新用户基本信息表
        this.updateById(
                weCustomer
        );


        WeFlowerCustomerRel weFlowerCustomerRel = WeFlowerCustomerRel.builder().build();
        BeanUtils.copyBeanProp(weFlowerCustomerRel, weCustomerPortrait);
        //更新企业添加人表
        iWeFlowerCustomerRelService.update(weFlowerCustomerRel, new LambdaQueryWrapper<WeFlowerCustomerRel>()
                .eq(WeFlowerCustomerRel::getExternalUserid, weCustomerPortrait.getExternalUserid())
                .eq(WeFlowerCustomerRel::getUserId, weCustomerPortrait.getUserId()));

    }


}
