package com.linkwechat.wecom.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.linkwechat.common.constant.Constants;
import com.linkwechat.common.constant.WeConstans;
import com.linkwechat.common.utils.SecurityUtils;
import com.linkwechat.common.utils.StringUtils;
import com.linkwechat.wecom.client.WeCropTagClient;
import com.linkwechat.wecom.domain.WeTag;
import com.linkwechat.wecom.domain.WeTagGroup;
import com.linkwechat.wecom.domain.dto.tag.*;
import com.linkwechat.wecom.domain.vo.tag.WeTagGroupVo;
import com.linkwechat.wecom.mapper.WeTagGroupMapper;
import com.linkwechat.wecom.service.IWeTagGroupService;
import com.linkwechat.wecom.service.IWeTagService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 标签组Service业务层处理
 *
 * @author ruoyi
 * @date 2020-09-07
 */
@Service
public class WeTagGroupServiceImpl extends ServiceImpl<WeTagGroupMapper, WeTagGroup> implements IWeTagGroupService {


    @Autowired
    private WeCropTagClient weCropTagClient;

    @Autowired
    private IWeTagService iWeTagService;


    /**
     * 查询标签组列表
     *
     * @param weTagGroup 标签组
     * @return 标签组
     */
    @Override
    public List<WeTagGroupVo> selectWeTagGroupList(WeTagGroup weTagGroup) {
        return this.baseMapper.selectWeTagGroupList(weTagGroup);
    }

    /**
     * 新增标签组
     *
     * @param weTagGroup 标签组
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertWeTagGroup(WeTagGroup weTagGroup) {

        List<WeTag> weTags = weTagGroup.getWeTags();

        if (CollectionUtil.isEmpty(weTags)) {
            this.save(weTagGroup);
        } else {

            WeCropGropTagDtlDto weCropGropTagDtlDto = weCropTagClient.addCorpTag(WeCropGroupTagDto.transformAddTag(weTagGroup));

            if (weCropGropTagDtlDto.getErrcode().equals(WeConstans.WE_SUCCESS_CODE)) {
                this.batchSaveOrUpdateTagGroupAndTag(ListUtil.toList(weCropGropTagDtlDto.getTag_group()), false);
            }

        }


    }

    /**
     * 修改标签组
     *
     * @param weTagGroup 标签组
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWeTagGroup(WeTagGroup weTagGroup) {

        List<WeTag> weTags = weTagGroup.getWeTags();
        //获取新增的集合
        if (CollectionUtil.isNotEmpty(weTags)) {
            List<WeTag> filterWeTags = weTags.stream().filter(v -> StringUtils.isEmpty(v.getTagId())).collect(Collectors.toList());

            //同步新增标签到微信端
            if (CollectionUtil.isNotEmpty(WeCropGroupTagDto.transformAddTag(weTagGroup).getTag())) {
                WeCropGropTagDtlDto
                        weCropGropTagDtlDto = weCropTagClient.addCorpTag(WeCropGroupTagDto.transformAddTag(weTagGroup));
                if (weCropGropTagDtlDto.getErrcode().equals(WeConstans.WE_SUCCESS_CODE)) {
                    //微信端返回的标签主键,设置到weTags中
                    Map<String, String> weCropTagMap = weCropGropTagDtlDto.getTag_group().getTag().stream()
                            .collect(Collectors.toMap(weCropTagDto -> weCropTagDto.getName(), weCropTagDto -> weCropTagDto.getId()));
                    filterWeTags.stream().forEach(tag -> {
                        tag.setTagId(weCropTagMap.get(tag.getName()));
                        tag.setCreateTime(new Date());
                    });
                }
            }


            //获取需要删除的数据
            List<WeTag> removeWeTags = iWeTagService.list(new LambdaQueryWrapper<WeTag>().notIn(WeTag::getTagId,
                    weTags.stream().map(WeTag::getTagId).collect(Collectors.toList())).eq(WeTag::getGroupId, weTagGroup.getGroupId())
                    .eq(WeTag::getDelFlag, Constants.NORMAL));

            if (CollectionUtil.isNotEmpty(removeWeTags)) {
                //同步删除微信端的标签
                weCropTagClient.delCorpTag(
                        WeCropDelDto.builder()
                                .group_id(ListUtil.toList(weTagGroup.getGroupId()))
                                .tag_id(removeWeTags.stream().map(WeTag::getTagId).collect(Collectors.toList()))
                                .build());

                //移除本地
                removeWeTags.stream().forEach(v -> v.setDelFlag(Constants.DELETE));
                iWeTagService.updateBatchById(removeWeTags);
            }


            //保存或更新wetag
            filterWeTags.stream().forEach(v -> v.setGroupId(weTagGroup.getGroupId()));
            iWeTagService.saveOrUpdateBatch(filterWeTags);

        }

    }


    /**
     * 批量删除标签组
     *
     * @param ids 需要删除的标签组ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteWeTagGroupByIds(List<String> ids) {
        boolean returnCode = this.removeByIds(ids);
        if (returnCode) {
            List<WeTag> weTags
                    = iWeTagService.list(new LambdaQueryWrapper<WeTag>().in(WeTag::getGroupId, ids));
            if (CollectionUtil.isNotEmpty(weTags)) {
                weCropTagClient.delCorpTag(
                        WeCropDelDto.builder()
                                .group_id(ids)
                                .tag_id(weTags.stream().map(WeTag::getTagId).collect(Collectors.toList()))
                                .build()
                );
            }
        }

        return returnCode;
    }


    /**
     * 同步标签
     */
    @Override
    @Transactional
    public void synchWeTags() {
        WeCropGroupTagListDto weCropGroupTagListDto = weCropTagClient.getAllCorpTagList();
        if (weCropGroupTagListDto.getErrcode().equals(WeConstans.WE_SUCCESS_CODE)) {
            this.batchSaveOrUpdateTagGroupAndTag(weCropGroupTagListDto.getTag_group(), true);
        }

    }


    /**
     * 来自微信端批量保存或者更新标签组和标签
     *
     * @param tagGroups
     * @param isSync   是否同步
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchSaveOrUpdateTagGroupAndTag(List<WeCropGroupTagDto> tagGroups, Boolean isSync) {

        List<WeTagGroup> weTagGroups = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(tagGroups)) {
            tagGroups.forEach(tagGroup -> {
                WeTagGroup weTagGroup = new WeTagGroup();
                weTagGroup.setCreateBy(SecurityUtils.getUsername());
                weTagGroup.setGroupName(tagGroup.getGroup_name());
                weTagGroup.setGroupId(tagGroup.getGroup_id());
                List<WeCropTagDto> tags = tagGroup.getTag();
                if (CollectionUtil.isNotEmpty(tags)) {
                    List<WeTag> weTags = new ArrayList<>();
                    tags.forEach(tag -> {
                        WeTag weTag = new WeTag();
                        weTag.setTagId(tag.getId());
                        weTag.setGroupId(weTagGroup.getGroupId());
                        weTag.setName(tag.getName());
                        weTags.add(weTag);
                    });
                    weTagGroup.setWeTags(weTags);
                }
                weTagGroups.add(weTagGroup);
            });
        }
        //先逻辑删除不存在得组
        if (CollectionUtil.isNotEmpty(weTagGroups)) {

            if (isSync) {
                List<WeTagGroup> noExist
                        = this.list(new LambdaQueryWrapper<WeTagGroup>().notIn(WeTagGroup::getGroupId, weTagGroups.stream().map(WeTagGroup::getGroupId).collect(Collectors.toList())));
                //企业微信端删除得标签
                if (CollectionUtil.isNotEmpty(noExist)) {
                    this.removeByIds(noExist.stream().map(WeTagGroup::getId).collect(Collectors.toList()));
                }
            }
            List<List<WeTagGroup>> tagGroupLists = Lists.partition(weTagGroups, 500);
            for (List<WeTagGroup> item : tagGroupLists) {
                this.baseMapper.insertWeTagGroupBatch(item);
            }

            List<WeTag> weTags =
                    weTagGroups.stream().map(WeTagGroup::getWeTags).collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll);
            if (CollectionUtil.isNotEmpty(weTags)) {
                if (isSync) {
                    List<WeTag> noExistWeTags
                            = iWeTagService.list(new LambdaQueryWrapper<WeTag>().notIn(WeTag::getTagId, weTags.stream().map(WeTag::getTagId).collect(Collectors.toList())));
                    if (CollectionUtil.isNotEmpty(noExistWeTags)) {
                        iWeTagService.removeByIds(noExistWeTags.stream().map(WeTag::getId).collect(Collectors.toList()));
                    }
                }

                List<List<WeTag>> lists = Lists.partition(weTags, 500);
                for (List<WeTag> item : lists) {
                    iWeTagService.insertWeTagBatch(item);
                }
            }
        } else {//不存在删除所有标签组,以标签
            if (isSync) {
                List<WeTagGroup> weTagGroupList
                        = this.list(new LambdaQueryWrapper<WeTagGroup>().eq(WeTagGroup::getDelFlag, Constants.NORMAL));
                if (CollectionUtil.isNotEmpty(weTagGroupList)) {
                    this.removeByIds(weTagGroupList.stream().map(WeTagGroup::getId).collect(Collectors.toList()));
                }
                List<WeTag> weTags
                        = iWeTagService.list(new LambdaQueryWrapper<WeTag>().eq(WeTag::getDelFlag, Constants.NORMAL));
                if (CollectionUtil.isNotEmpty(weTags)) {
                    iWeTagService.removeByIds(weTags.stream().map(WeTag::getId).collect(Collectors.toList()));
                }
            }
        }
    }

    @Override
    public void createTagGroup(String id) {
        WeFindCropTagParam build = WeFindCropTagParam.builder().group_id(ListUtil.toList(id)).build();
        WeCropGroupTagListDto weCropGroupTagListDto = weCropTagClient.getCorpTagListByTagIds(build);
        List<WeCropGroupTagDto> tagGroups = weCropGroupTagListDto.getTag_group();
        if (CollectionUtil.isNotEmpty(tagGroups)) {
            List<WeTagGroup> tagGroupsList = new ArrayList<>();
            tagGroups.forEach(k -> WeTagGroup.builder().groupId(k.getGroup_id()).groupName(k.getGroup_name()).build());
            this.baseMapper.insertWeTagGroupBatch(tagGroupsList);
        }
    }

    @Override
    public void deleteTagGroup(String groupId) {
        remove(new LambdaQueryWrapper<WeTagGroup>().eq(WeTagGroup::getGroupId,groupId));
    }

    @Override
    public void updateTagGroup(String id) {
        WeFindCropTagParam build = WeFindCropTagParam.builder().group_id(ListUtil.toList(id)).build();
        WeCropGroupTagListDto weCropGroupTagListDto = weCropTagClient.getCorpTagListByTagIds(build);
        List<WeCropGroupTagDto> tagGroups = weCropGroupTagListDto.getTag_group();
        if (CollectionUtil.isNotEmpty(tagGroups)) {
            List<WeTagGroup> tagGroupsList = new ArrayList<>();
            tagGroups.forEach(k -> WeTagGroup.builder().groupId(k.getGroup_id()).groupName(k.getGroup_name()).build());
            this.baseMapper.insertWeTagGroupBatch(tagGroupsList);
        }
    }

    @Override
    public List<WeTagGroupVo> findCustomerTag(String externalUserid, String userId, Integer type) {
        return this.baseMapper.findCustomerTag(externalUserid, userId, type);
    }


}
