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

import static org.slf4j.LoggerFactory.getLogger;

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

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.commons.util.ToolUtil;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.manage.api.dto.HandoverExternalDTO;
import com.gic.haoban.manage.api.dto.HandoverStaffFriendCountDTO;
import com.gic.haoban.manage.api.dto.SecretSettingDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.enums.SecretTypeEnum;
import com.gic.haoban.manage.service.dao.mapper.HandoverExternalMapper;
import com.gic.haoban.manage.service.dao.mapper.HandoverStaffMapper;
import com.gic.haoban.manage.service.dao.mapper.HandoverTransferMapper;
import com.gic.haoban.manage.service.dao.mapper.StaffMapper;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanClerkMainStoreRelatedMapper;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanExternalClerkRelatedMapper;
import com.gic.haoban.manage.service.entity.TabHandoverExternal;
import com.gic.haoban.manage.service.entity.TabHandoverStaff;
import com.gic.haoban.manage.service.entity.TabHandoverTransfer;
import com.gic.haoban.manage.service.entity.TabHaobanClerkMainStoreRelated;
import com.gic.haoban.manage.service.entity.TabHaobanExternalClerkRelated;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.service.HandoverService;
import com.gic.haoban.manage.service.service.SecretSettingService;
import com.gic.haoban.manage.service.service.StaffClerkRelationService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.wechat.api.dto.qywx.QywxTransferCustomerInfoDTO;
import com.gic.wechat.api.dto.qywx.QywxUnassignedInfoDTO;
import com.gic.wechat.api.dto.qywx.UserDTO;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Sets;

/**
 * Created 2021/6/15.
 *
 * @author hua
 */
@Service
public class HandoverServiceImpl implements HandoverService {

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

    @Autowired
    private HandoverStaffMapper handoverStaffMapper;
    @Autowired
    private HandoverExternalMapper handoverExternalMapper;
    @Autowired
    private HandoverTransferMapper handoverTransferMapper;
    @Autowired
    private StaffMapper staffMapper;
    @Autowired
    private TabHaobanExternalClerkRelatedMapper externalClerkRelatedMapper;
    @Autowired
    private QywxUserApiService qywxUserApiService;
    @Autowired
    private SecretSettingService secretSettingService;
    @Autowired
    private TabHaobanClerkMainStoreRelatedMapper clerkMainStoreRelatedMapper;
    @Autowired
    private StaffClerkRelationService staffClerkRelationService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService ;

    @Override
    public boolean saveHandover(String wxEnterpriseId, List<QywxUnassignedInfoDTO> infoList) {
        logger.info("saveHandover-保存离职基础数据：{}", wxEnterpriseId);
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        if (CollectionUtils.isEmpty(infoList)) {
            logger.info("没有要保存的数据，删除所有需要删除逇");
            delHandoverStaff(wxEnterpriseId, null);
            return false;
        }
        SecretSettingDTO secretSetting = secretSettingService.getSecretSetting(qwDTO.getWxEnterpriseId(), SecretTypeEnum.CUSTOMIZED_APP.getVal());
        if (null == secretSetting || secretSetting.getCheckFlag() == 0) {
            logger.info("没有配置secret：{}", JSONObject.toJSONString(qwDTO));
            return false;
        }

        Map<String, List<QywxUnassignedInfoDTO>> handoverUserMap = infoList.stream().collect(Collectors.groupingBy(dto -> dto.getHandoverUserid()));
        handoverUserMap.forEach((userId, list) -> {
            boolean checkFlag = checkStaffOver(secretSetting, userId, qwDTO.getDkCorpid() ,qwDTO);
            if (checkFlag) {
                logger.info("该用户存在，不需要离职基础：{},{}", userId, wxEnterpriseId);
                return;
            }
            TabHandoverStaff handoverStaff = getHandoverStaff(wxEnterpriseId, userId);
            if (null == handoverStaff) {
                return;
            }
            List<TabHandoverExternal> externalList = list.stream().map(dto -> {
                TabHandoverExternal mid = getHandExternal(dto, qwDTO.getWxEnterpriseId(), handoverStaff);
                mid.setStaffId(handoverStaff.getStaffId());
                handoverStaff.setDimissionTime(dto.getDimissionTimeDate());
                mid.setStatusFlag(mid.getStatusFlag() != null ? mid.getStatusFlag() : 1);
                mid.setUserId(dto.getHandoverUserid());
                return mid;
            }).collect(Collectors.toList());
            //个数
            int sum = externalList.stream().filter(dto -> dto.getHaobanFriendFlag() == 1).mapToInt(dto -> 1).sum();
            handoverStaff.setFriendCount(externalList.size());
            handoverStaff.setHaobanFriendCount(sum);
            //保存
            List<TabHandoverExternal> needAdd = externalList.stream().filter(dto -> dto.getHandoverExternalId() == null).collect(Collectors.toList());
            saveHandoverStaff(handoverStaff);
            if (CollectionUtils.isNotEmpty(needAdd)) {
                needAdd.forEach(mid -> {
                    mid.setHandoverExternalId(ToolUtil.randomUUID());
                });
                handoverExternalMapper.insertBatch(needAdd);
            }
        });
        //删除不需要的staff数据
        List<TabHandoverStaff> handoverStaffList = handoverStaffMapper.listByWxEnterpriseId(wxEnterpriseId);
        if (CollectionUtils.isEmpty(handoverStaffList)) {
            logger.info("没有新数据，无需删除");
            return true;
        }
        Set<String> hasWxUserIds = handoverStaffList.stream().map(dto -> dto.getHandoverUserId()).collect(Collectors.toSet());
        Sets.SetView<String> needDelUserIds = Sets.difference(hasWxUserIds, handoverUserMap.keySet());
        if (CollectionUtils.isEmpty(needDelUserIds)) {
            logger.info("没有新数据，无需删除2");
            return true;
        }
        logger.info("删除数据");
        delHandoverStaff(wxEnterpriseId, new ArrayList<>(needDelUserIds));
        return false;
    }

    private boolean checkStaffOver(SecretSettingDTO secretSetting, String userId, String corpId,WxEnterpriseQwDTO qwDTO) {
        UserDTO user = qywxUserApiService.getSelfWorkWxUser(corpId, secretSetting.getSecretVal(), userId , qwDTO.getUrlHost());
        if (null == user) {
            return false;
        }
        return true;
    }

    /**
     * 删除企业下的数据
     *
     * @param wxEnterpriseId
     * @param wxUserIds
     */
    private void delHandoverStaff(String wxEnterpriseId, List<String> wxUserIds) {
        handoverStaffMapper.delByUserIds(wxEnterpriseId, wxUserIds);
        handoverExternalMapper.delNoTransferExternal(wxUserIds, wxEnterpriseId);
    }

    private void saveHandoverStaff(TabHandoverStaff handoverStaff) {
        if (handoverStaff.getHandoverStaffId() != null) {
            handoverStaff.setUpdateTime(new Date());
            handoverStaffMapper.updateByPrimaryKeySelective(handoverStaff);
        } else {
            handoverStaff.setHandoverStaffId(ToolUtil.randomUUID());
            handoverStaffMapper.insertSelective(handoverStaff);
            //解绑
            List<String> staffIds = new ArrayList<>();
            staffIds.add(handoverStaff.getStaffId());
            staffClerkRelationService.cleanStaffClerk(handoverStaff.getWxEnterpriseId(), staffIds);
        }
    }
    @Override
    public TabHandoverStaff getHandoverStaff(String wxEnterpriseId, String wxUserId) {
        TabHaobanStaff haobanStaff = staffMapper.getNoStatusByWxUserIds(wxEnterpriseId, wxUserId);
        if (null == haobanStaff) {
            logger.info("对应的staff不存在：{}", wxUserId);
            return null;
        }
        TabHandoverStaff handoverStaff = handoverStaffMapper.getByStaffId(wxEnterpriseId, haobanStaff.getStaffId());
        if (null != handoverStaff) {
            logger.info("对应的handoverStaff不存在：{}", haobanStaff.getStaffId());
            return handoverStaff;
        }
        handoverStaff = new TabHandoverStaff();
        TabHaobanClerkMainStoreRelated clerkMainStoreRelated = clerkMainStoreRelatedMapper.getLastNoStatusByStaffId(wxEnterpriseId, haobanStaff.getStaffId());
        if (null == clerkMainStoreRelated) {
            logger.info("没有主门店：{}", haobanStaff.getStaffId());
            // 需要过滤 没有主门店的人 不需要执行
            return null;
//            return null;
        } else {
            handoverStaff.setStoreId(clerkMainStoreRelated.getStoreId());
        }
        handoverStaff.setStaffId(haobanStaff.getStaffId());
        handoverStaff.setHandoverUserId(wxUserId);
        handoverStaff.setWxEnterpriseId(wxEnterpriseId);
//        handoverStaff.setHandoverStaffId(ToolUtil.randomUUID());
        handoverStaff.setCreateTime(new Date());
        handoverStaff.setUpdateTime(new Date());
        handoverStaff.setStatusFlag(1);
        handoverStaff.setStaffId(haobanStaff.getStaffId());
        return handoverStaff;
    }

    /**
     * 获取外部联系人
     *
     * @param infoDTO
     * @return
     */
    private TabHandoverExternal getHandExternal(QywxUnassignedInfoDTO infoDTO, String wxEnterpriseId, TabHandoverStaff handoverStaff) {
        TabHandoverExternal handoverExternal = handoverExternalMapper.getByExternalUserIdAndStaffId(wxEnterpriseId, handoverStaff.getStaffId(), infoDTO.getExternalUserid());
        if (null != handoverExternal) {
            return handoverExternal;
        }
        TabHandoverExternal mid = new TabHandoverExternal();
        mid.setExternalUserId(infoDTO.getExternalUserid());
        mid.setWxEnterpriseId(wxEnterpriseId);
        mid.setHaobanFriendFlag(0);
        TabHaobanExternalClerkRelated externalClerkRelated = externalClerkRelatedMapper.getLastByExTernalUseridAndWxUserIdNoStatus(wxEnterpriseId, infoDTO.getExternalUserid(), handoverStaff.getStaffId());
        if (null == externalClerkRelated) {
            mid.setExternalUserName("企业微信客户");
            mid.setRelationId("-1");
        } else {
            mid.setRelationId(externalClerkRelated.getExternalClerkRelatedId());
            mid.setExternalUserName(externalClerkRelated.getExternalName());
            mid.setHaobanFriendFlag(1);
            mid.setExternalHeadUrl(externalClerkRelated.getHeadUrl());
        }
        return mid;
    }

    @Override
    public List<TabHandoverStaff> listByStoreId(String wxEnterpriseId, String storeId) {
        List<TabHandoverStaff> handoverStaffs = handoverStaffMapper.listByStoreId(wxEnterpriseId, storeId);
        if (CollectionUtils.isEmpty(handoverStaffs)) {
            return null;
        }
        return handoverStaffs;
    }

    @Override
    public Page<HandoverExternalDTO> pageByStaffIds(String wxEnterpriseId, String search, List<String> staffIds, List<String> transferIds, BasePageInfo pageInfo, Integer status) {
        PageHelper.startPage(pageInfo);
        List<TabHandoverExternal> externalList = handoverExternalMapper.listByStaffIds(wxEnterpriseId, transferIds, staffIds, search, status);
        Page<HandoverExternalDTO> retPage = PageUtil.changePageHelperToCurrentPage(new PageInfo<>(externalList), HandoverExternalDTO.class);
        return retPage;
    }

    @Override
    public List<TabHandoverExternal> listByIds(String wxEnterpriseId, List<String> ids) {
        return handoverExternalMapper.listByIds(wxEnterpriseId, ids);
    }

    @Override
    public String saveHandoverTransfer(TabHandoverTransfer transfer, List<String> handoverExternalIds) {
        TabHandoverTransfer tabHandoverTransfer = handoverTransferMapper.getByHandoverStaffIdAndTakeoverStaffId(transfer.getWxEnterpriseId(), transfer.getHandoverStaffId(), transfer.getTakeoverStaffId());
        String transferId = null;
        if (null != tabHandoverTransfer) {
            handoverTransferMapper.addCount(tabHandoverTransfer.getHandoverTransferId(), transfer.getExternalCount());
            transferId = tabHandoverTransfer.getHandoverTransferId();
        } else {
            transfer.setHandoverTransferId(ToolUtil.randomUUID());
            transfer.setStatusFlag(1);
            transfer.setCreateTime(new Date());
            transfer.setUpdateTime(new Date());
            handoverTransferMapper.insertSelective(transfer);
            transferId = transfer.getHandoverTransferId();
        }
        //分配初始化
        handoverExternalMapper.updateAfterTransfer(handoverExternalIds, transferId);
        return transferId;
    }

    @Override
    public List<TabHandoverTransfer> listTransferByStoreId(String wxEnterpriseId, String storeId) {
        List<TabHandoverTransfer> handoverTransfers = handoverTransferMapper.listTransferByStoreId(wxEnterpriseId, storeId);
        return handoverTransfers;
    }

    @Override
    public List<TabHandoverTransfer> listTransferByHandoverStaffId(String wxEnterpriseId, String handoverStaffId) {
        return handoverTransferMapper.listTransferByHandoverStaffId(wxEnterpriseId, handoverStaffId);
    }

    @Override
    public List<TabHandoverTransfer> listTransferByTakeoverStaffId(String wxEnterpriseId, String takeoverStaffId) {
        return handoverTransferMapper.listTransferByTakeoverStaffId(wxEnterpriseId, takeoverStaffId);
    }

    @Override
    public List<TabHandoverTransfer> listTransferByIds(String wxEnterpriseId, List<String> ids) {
        return handoverTransferMapper.listTransferByIds(wxEnterpriseId, ids);
    }

    @Override
    public List<TabHandoverTransfer> listTransferByWxEnterpriseId(String wxEnterpriseId, String date) {
        List<TabHandoverTransfer> ret = handoverTransferMapper.listTransferByWxEnterpriseId(wxEnterpriseId, date);
        return ret;
    }

    @Override
    public boolean dealResult(String wxEnterpriseId, String transferId, List<QywxTransferCustomerInfoDTO> list) {
        if (CollectionUtils.isEmpty(list)) {
            logger.info("没有需要处理的" + wxEnterpriseId);
            return false;
        }

        list.forEach(dto -> {
            try {
                TabHandoverExternal handoverExternal = handoverExternalMapper.getByTransferId(wxEnterpriseId, transferId, dto.getExternalUserid());
                if (handoverExternal == null) {
                    logger.info("不存在该人员，有问题：{}", dto.getExternalUserid());
                    return;
                }
                if (dto.getTakeoverTime() != null && dto.getTakeoverTime() > 0) {
                    Date date = new Date(dto.getTakeoverTime() * 1000);
                    handoverExternal.setTakeoverTime(date);
                }
                handoverExternal.setTransferStatus(dto.getStatus());
                handoverExternal.setUpdateTime(new Date());
                handoverExternalMapper.updateByPrimaryKeySelective(handoverExternal);
            } catch (Exception e) {
                logger.info("exception:{},{}", JSONObject.toJSONString(dto), e);
                e.printStackTrace();
            }
        });
        return true;
    }

    @Override
    public List<HandoverStaffFriendCountDTO> listFriendCountByWxStaffIds(String wxEnterpriseId, List<String> staffIds) {
        List<HandoverStaffFriendCountDTO> ret = handoverExternalMapper.listPreCountByStaffIds(wxEnterpriseId, staffIds);
        return ret;
    }
}
