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

import com.alibaba.fastjson.JSONObject;
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.DateUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.haoban.manage.api.dto.CommonMQDTO;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.moment.QwMomentPlanAttendDTO;
import com.gic.haoban.manage.api.dto.moment.TaskDetailDTO;
import com.gic.haoban.manage.api.dto.moment.TaskListWxaDTO;
import com.gic.haoban.manage.api.qdto.moment.PlanClerkListQDTO;
import com.gic.haoban.manage.api.qdto.moment.SendResultQDTO;
import com.gic.haoban.manage.api.qdto.moment.TaskListWxaQDTO;
import com.gic.haoban.manage.api.service.HaobanCommonMQApiService;
import com.gic.haoban.manage.api.service.StaffClerkRelationApiService;
import com.gic.haoban.manage.service.dao.mapper.StaffMapper;
import com.gic.haoban.manage.service.dao.mapper.moment.QwMomentPlanAttendMapper;
import com.gic.haoban.manage.service.dao.mapper.moment.QwMomentPlanMapper;
import com.gic.haoban.manage.service.entity.TabHaobanClerkMainStoreRelated;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.moment.TabQwMomentPlan;
import com.gic.haoban.manage.service.entity.moment.TabQwMomentPlanAttend;
import com.gic.haoban.manage.service.pojo.ClerkStaffBO;
import com.gic.haoban.manage.service.service.ClerkMainStoreRelatedService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.service.moment.QwMomentPlanAttendService;
import com.gic.haoban.manage.service.service.moment.QwMomentPlanService;
import com.gic.haoban.manage.service.service.notify.PendingTaskService;
import com.gic.wechat.api.dto.qdto.group.QywxMomentInfoQDTO;
import com.gic.wechat.api.dto.qywx.group.QywxMomentRespDTO;
import com.gic.wechat.api.service.qywx.QywxSuiteApiService;
import com.github.pagehelper.PageHelper;
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.stream.Collectors;

@Service("qwMomentPlanAttendService")
public class QwMomentPlanAttendServiceImpl implements QwMomentPlanAttendService {

    private final Logger logger = LogManager.getLogger(this.getClass());

    @Autowired
    private QwMomentPlanAttendMapper qwMomentPlanAttendMapper ;
    @Autowired
    private ClerkService clerkService ;
    @Autowired
    private QywxSuiteApiService qywxSuiteApiService ;
    @Autowired
    private WxEnterpriseService wxEnterpriseService ;
    @Autowired
    private StaffMapper staffMapper ;
    @Autowired
    private QwMomentPlanMapper qwMomentPlanMapper ;
    @Autowired
    private StaffClerkRelationApiService staffClerkRelationApiService ;
    @Autowired
    private QwMomentPlanService qwMomentPlanService ;
    @Autowired
    private PendingTaskService pendingTaskService ;
    @Autowired
    private HaobanCommonMQApiService haobanCommonMQApiService ;
    @Autowired
    private ClerkMainStoreRelatedService clerkMainStoreRelatedService ;

    @Override
    public ServiceResponse<Page<QwMomentPlanAttendDTO>> attendList(PlanClerkListQDTO qdto) {
        // 0已失效 1待完成 2已完成
        Integer sendStatus = qdto.getSendStatus() ;
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(qdto.getPlanId()) ;
        boolean isEnd = plan.getStatusFlag()==2 || plan.getEndDate().getTime() <= System.currentTimeMillis() ;
        if(null != sendStatus && isEnd && sendStatus==1) {
            return ServiceResponse.success(new Page<>());
        }
        if(null != sendStatus && !isEnd && sendStatus==0) {
            return ServiceResponse.success(new Page<>());
        }
        PageHelper.startPage(qdto);
        if(StringUtils.isNotEmpty(qdto.getClerkParams())) {
            qdto.setClerkParamsLike("%"+qdto.getClerkParams()+"%");
        }
        if(StringUtils.isNotBlank(qdto.getStaffName())) {
            qdto.setStaffNameLike("%"+qdto.getStaffName()+"%");
        }
        if(StringUtils.isBlank(qdto.getSortColumn())) {
            qdto.setSortColumn("create_time");
        }
        if(StringUtils.isBlank(qdto.getSortType())) {
            qdto.setSortType("desc");
        }
        List<QwMomentPlanAttendDTO> list = this.qwMomentPlanAttendMapper.list(qdto);
        Page<QwMomentPlanAttendDTO> retPage = PageHelperUtils.changePageHelperToCurrentPage(list, QwMomentPlanAttendDTO.class);
        if(CollectionUtils.isNotEmpty(retPage.getResult())  && null != sendStatus && sendStatus==0) {
            retPage.getResult().forEach(o->o.setTaskStatus(0));
        }
        return ServiceResponse.success(retPage);
    }

    @Override
    public void saveClerk(String wxEnterpriseId , String enterpriseId, Long planId , List<ClerkStaffBO> clerkStaffList , int statusFlag) {
        if(CollectionUtils.isEmpty(clerkStaffList)) {
            return;
        }
        List<String> clerkIdList = clerkStaffList.stream().map(o->o.getClerkId()).collect(Collectors.toList());
        List<String> existClerkIdList = this.qwMomentPlanAttendMapper.listExistClerkIds(planId,clerkIdList) ;
        if(CollectionUtils.isNotEmpty(existClerkIdList)) {
            clerkIdList = clerkIdList.stream().filter(o->!existClerkIdList.contains(o)).collect(Collectors.toList());
        }
        if(CollectionUtils.isEmpty(clerkIdList)) {
            logger.info("所有导购都已添加过");
            return ;
        }
        List<TabQwMomentPlanAttend> list = new ArrayList<>() ;
        for(ClerkStaffBO bo :  clerkStaffList) {
            String clerkId = bo.getClerkId() ;
            ClerkDTO clerkDTO = this.clerkService.getclerkById(clerkId) ;
            if(null != clerkDTO) {
                TabQwMomentPlanAttend attend = new TabQwMomentPlanAttend() ;
                attend.setAttendId(UniqueIdUtils.uniqueLong());
                attend.setPlanId(planId);
                attend.setWxEnterpriseId(wxEnterpriseId);
                attend.setEnterpriseId(enterpriseId);
                attend.setStaffId(bo.getStaffId());
                attend.setClerkId(clerkId);
                attend.setClerkCode(clerkDTO.getClerkCode());
                attend.setClerkName(clerkDTO.getClerkName());
                attend.setStoreId(clerkDTO.getStoreId());
                attend.setTaskStatus(1);
                attend.setStatusFlag(statusFlag);
                list.add(attend) ;
            }
        }
        this.qwMomentPlanAttendMapper.batchInsert(list);
        if(statusFlag == 1) {
            this.qwMomentPlanMapper.updateClerkNum(planId,list.size(), list.size(), -1);
        }else {
            this.qwMomentPlanMapper.updateClerkNum(planId,list.size(), -1, -1);
        }
    }

    @Override
    public void updateStatusFlag(TabQwMomentPlan plan) {
        List<QwMomentPlanAttendDTO> allList = this.qwMomentPlanAttendMapper.listClerk(plan.getPlanId(),0) ;
        if(CollectionUtils.isEmpty(allList)) {
            return;
        }
        int totalSize = allList.size() ;
        List<String> clerkIdList = allList.stream().map(o->o.getClerkId()).collect(Collectors.toList());
        List<StaffClerkRelationDTO> list = this.staffClerkRelationApiService.listByClerkIdsWxEnterpriseId(clerkIdList,plan.getWxEnterpriseId()) ;
        Map<String,String> map = list.stream().collect(Collectors.toMap(o->o.getClerkId(),StaffClerkRelationDTO::getStaffId,(k1, k2)->k1)) ;
        if(CollectionUtils.isEmpty(list)) {
            this.qwMomentPlanAttendMapper.updateFail(plan.getPlanId(), clerkIdList,"任务下发时未绑定企微号");
        }else {
            List<String> noStaff = allList.stream().filter(o->map.keySet().contains(o.getClerkId())).map(o->o.getClerkId()).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(noStaff)) {
                this.qwMomentPlanAttendMapper.updateFail(plan.getPlanId(), clerkIdList,"任务下发时未绑定企微号");
            }
            List<String> successList = new ArrayList<>() ;
            for(QwMomentPlanAttendDTO dto : allList) {
                String cid = dto.getClerkId() ;
                String sid = dto.getStaffId() ;
                if(map.get(cid) != null && map.get(cid).equals(sid)) {
                }else {
                    this.qwMomentPlanAttendMapper.updateSuccessStaff(plan.getPlanId(),cid,map.get(cid));
                }
                TabHaobanClerkMainStoreRelated tab =this.clerkMainStoreRelatedService.getMainStoreByStaffId(sid,plan.getWxEnterpriseId()) ;
                if(null == tab || !tab.getStoreId().equals(dto.getStoreId())) {
                    this.qwMomentPlanAttendMapper.updateFail(plan.getPlanId(), clerkIdList,"任务下发时不是主门店");
                    continue;
                }
                successList.add(cid) ;
            }
            if(CollectionUtils.isNotEmpty(successList)) {
                this.qwMomentPlanAttendMapper.updateSuccess(plan.getPlanId(), successList);
            }
        }
        int failCount = 0 ;
        List<QwMomentPlanAttendDTO> failList = this.qwMomentPlanAttendMapper.listClerk(plan.getPlanId(),2) ;
        if(CollectionUtils.isNotEmpty(failList)) {
            failCount = failList.size() ;
        }
        this.qwMomentPlanMapper.updateClerkNum(plan.getPlanId(), totalSize, totalSize-failCount,-1);
    }


    @Override
    public ServiceResponse<TaskDetailDTO> taskDetail(Long planId, String execClerkId) {
        TaskDetailDTO dto = this.qwMomentPlanAttendMapper.taskDetail(planId,execClerkId) ;
        if(null == dto) {
            return ServiceResponse.failure("9999","活动不存在或已删除");
        }
        Long attendId = dto.getAttendId() ;
        TabQwMomentPlanAttend attend = this.qwMomentPlanAttendMapper.getById(attendId) ;
        TabQwMomentPlan plan = this.qwMomentPlanMapper.getById(planId) ;
        if(null == plan) {
            return ServiceResponse.failure("9999","活动不存在或已删除");
        }
        if(plan.getStatusFlag()==1 && plan.getEndDate().getTime() + 1000*60*60*24*3L > System.currentTimeMillis()) {
            this.qwMomentPlanService.getQwData(attend, 1, plan.getMomentId());
        }
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<Page<TaskListWxaDTO>> taskListWxa(TaskListWxaQDTO qdto) {
        PageHelper.startPage(qdto);
        List<TaskListWxaDTO> list = this.qwMomentPlanAttendMapper.taskListWxa(qdto);
        Page<TaskListWxaDTO> retPage = PageHelperUtils.changePageHelperToCurrentPage(list, TaskListWxaDTO.class);
        return ServiceResponse.success(retPage);
    }

    @Override
    public ServiceResponse<Void> finishTask(SendResultQDTO qdto) {
        Long planId = qdto.getPlanId() ;
        String clerkId = qdto.getClerkId() ;
        TaskDetailDTO dto = this.qwMomentPlanAttendMapper.taskDetail(planId,clerkId) ;
        if(null == dto) {
            return ServiceResponse.failure("9999","任务不存在");
        }
        this.finishTaskUpdateData(dto.getAttendId(),planId,qdto.getSendTime(),qdto.getStaffId()) ;
        String momentId = this.getMomentId(qdto.getStaffId() , qdto.getSendTime() , 0) ;
        if(StringUtils.isNotBlank(momentId)) {
            this.qwMomentPlanAttendMapper.updateMomentId(dto.getAttendId(),momentId);
        }else {
            logger.info("未获取到,延迟获取={},{}",planId,qdto.getStaffId()) ;
            CommonMQDTO mq = new CommonMQDTO() ;
            mq.setType(7) ;
            Map<String,String> map = new HashMap<>() ;
            map.put("attendId",dto.getAttendId()+"") ;
            map.put("times", "1");
            mq.setParams(map);
            this.haobanCommonMQApiService.putCommonDelayMessage(mq, 10);
        }
        return ServiceResponse.success() ;
    }

    @Override
    public void updateMomentId(Long attendId , int times) {
        TabQwMomentPlanAttend tab = this.qwMomentPlanAttendMapper.getById(attendId) ;
        String momentId = this.getMomentId(tab.getStaffId() , tab.getSendTime() , times) ;
        if(StringUtils.isNotBlank(momentId)) {
            this.qwMomentPlanAttendMapper.updateMomentId(attendId, momentId);
        }else {
            if(times >= 10) {
                return;
            }
            logger.info("未获取到,延迟获取={},{}",tab.getPlanId(),tab.getStaffId()) ;
            CommonMQDTO mq = new CommonMQDTO() ;
            mq.setType(7) ;
            Map<String,String> map = new HashMap<>() ;
            map.put("attendId",attendId+"") ;
            map.put("times", (times+1)+"");
            mq.setParams(map);
            this.haobanCommonMQApiService.putCommonDelayMessage(mq, 10);
        }
    }

    @Override
    public void finishTaskUpdateData(Long attendId , Long planId , Date sendDate , String staffId) {
        TabQwMomentPlanAttend attend = this.qwMomentPlanAttendMapper.getById(attendId) ;
        if(attend.getTaskStatus()==2) {
            return;
        }
        this.qwMomentPlanAttendMapper.finishTask(attendId,sendDate,staffId) ;
        this.qwMomentPlanMapper.updateClerkNum(planId,-1,-1,1);
        // 完成代办
        this.pendingTaskService.updateFinish(attendId+"") ;
    }

    private String getMomentId(String staffId , Date sendTime , int  times) {
        Date startTime =  DateUtil.addNumForSecond(sendTime,-(60 + times * 60)) ;
        Date endTime = DateUtil.addNumForMinute(sendTime,1) ;
        TabHaobanStaff staff =  this.staffMapper.selectByPrimaryKey(staffId) ;
        String wxEnterpriseId = staff.getWxEnterpriseId() ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        String wxUserId = staff.getWxUserId() ;
        if(qwDTO.needOpenUserId3th()) {
            wxUserId = staff.getWxOpenUseId() ;
        }
        QywxMomentInfoQDTO qywxMomentInfoQDTO = new QywxMomentInfoQDTO();
        qywxMomentInfoQDTO.setCorpid(qwDTO.getThirdCorpid());
        qywxMomentInfoQDTO.setSuiteid(qwDTO.getSelf3thSecret());
        qywxMomentInfoQDTO.setStartTime(startTime.getTime() / 1000);
        qywxMomentInfoQDTO.setEndTime(endTime.getTime() / 1000);
        qywxMomentInfoQDTO.setCreatorId(wxUserId);
        qywxMomentInfoQDTO.setPageSize(1);
        ServiceResponse<QywxMomentRespDTO> serviceResponse = qywxSuiteApiService.queryQywxMomentList(qywxMomentInfoQDTO,qwDTO.isSelf(),qwDTO.getUrlHost());
        logger.info("查询朋友圈id={},{},{}",staffId,sendTime, JSONObject.toJSONString(serviceResponse));
        List<QywxMomentRespDTO.QywxMomentInfoDTO> list = serviceResponse.getResult().getQywxMomentInfos() ;
        if(CollectionUtils.isNotEmpty(list)) {
            return list.get(0).getMomentId() ;
        }
        return null  ;
    }
}
