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

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
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.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 com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.EntityUtil;
import com.gic.haoban.common.utils.DingUtils;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.CommonMQDTO;
import com.gic.haoban.manage.api.dto.DepartmentDTO;
import com.gic.haoban.manage.api.dto.SecretSettingDTO;
import com.gic.haoban.manage.api.dto.StaffDepartmentRelatedDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.enums.SecretTypeEnum;
import com.gic.haoban.manage.api.service.HaobanCommonMQApiService;
import com.gic.haoban.manage.service.dao.mapper.StaffDepartmentRelatedMapper;
import com.gic.haoban.manage.service.dao.mapper.StaffMapper;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.TabHaobanStaffDepartmentRelated;
import com.gic.haoban.manage.service.service.DepartmentService;
import com.gic.haoban.manage.service.service.SecretSettingService;
import com.gic.haoban.manage.service.service.StaffDepartmentRelatedService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.wechat.api.dto.qywx.UserDTO;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.google.common.collect.Sets;

@Service
public class StaffDepartmentRelatedServiceImpl implements StaffDepartmentRelatedService {
	
    private static final Logger logger = LogManager.getLogger(StaffDepartmentRelatedService.class);
	@Autowired
	private StaffDepartmentRelatedMapper mapper;
	@Autowired
	private StaffMapper staffMapper ;
	@Autowired
	private SecretSettingService secretSettingService ;
	@Autowired
	private WxEnterpriseService wxEnterpriseService ;
	@Autowired
	private QywxUserApiService qywxUserApiService ;
	@Autowired
	private DepartmentService departmentService ;
	@Autowired
	private HaobanCommonMQApiService haobanCommonMQApiService ;
	
	@Override
	public List<TabHaobanStaffDepartmentRelated> listByDepartmentId(String departmentId) {
		return mapper.listByDepartmentId(departmentId);
	}

	@Override
	public String add(StaffDepartmentRelatedDTO related) {
		Date now = new Date();
		related.setCreateTime(now);
		related.setUpdateTime(now);
		related.setStatusFlag(1);
		related.setStaffDepartmentRelatedId(StringUtil.randomUUID());
		TabHaobanStaffDepartmentRelated tab = EntityUtil.changeEntityByJSON(TabHaobanStaffDepartmentRelated.class, related);
		mapper.insert(tab);
		return related.getStaffDepartmentRelatedId();
	}

	@Override
	public List<TabHaobanStaffDepartmentRelated> listStaffDepartmentByStaffId(String staffId) {
		return mapper.listStaffDepartmentByStaffId(staffId);
	}

	@Override
	public void del(StaffDepartmentRelatedDTO related) {
		TabHaobanStaffDepartmentRelated tab  = EntityUtil.changeEntityByJSON(TabHaobanStaffDepartmentRelated.class, related);
		tab.setStatusFlag(0);
		tab.setUpdateTime(new Date());
		mapper.updateByPrimaryKeySelective(tab);
	}

	@Override
	public void delByStaffid(String staffid) {
		mapper.delByStaffid(staffid);
	}

//	@Override
//	public TabHaobanStaffDepartmentRelated getDepartmentIdAndStaffId(String departmentId, String staffId) {
//		return mapper.getDepartmentIdAndStaffId(departmentId,staffId);
//	}

	@Override
	public int cleanStaffDepartment(String wxEnterpriseId, List<String> staffIds) {
		return mapper.cleanStaffDepartment(wxEnterpriseId,staffIds);
	}

	@Override
	public int update(TabHaobanStaffDepartmentRelated tab) {
		return mapper.updateByPrimaryKeySelective(tab);
	}
	
	@Override
	public void repairAllStaffDepart(String params) {
	    logger.info("修复无部门成员={}",params);
	    int addDay = 0 ;
	    String wxEnterpriseId = null ;
	    if(params.contains("#")) {
	        addDay = Integer.parseInt(params.split("#")[0]) ;
	        wxEnterpriseId =  params.split("#")[1] ;
	    }else {
	        addDay = Integer.parseInt(params) ;
	    }
	    Date addDate = DateUtil.addDay(DateUtil.getStartTimeOfDay(),-addDay) ;
	    List<String> list = this.mapper.listNoDepartStaff(wxEnterpriseId, addDate) ;
	    if(CollectionUtils.isNotEmpty(list)) {
	        logger.info("修复成员部门,成员数={}",list.size());
	        DingUtils.send("修复无部门成员消息,数量="+list.size(), false);
	        for(String staffId : list) {
	            this.repairStaffDepart(staffId);
	        }
	    }
	    logger.info("修复成员部门完成={}",params);
	}
	
	@Override
	public void repairStaffDepart(String staffId) {
	    logger.info("修复无部门成员,staffId={}",staffId);
	    TabHaobanStaff staff =  this.staffMapper.selectByPrimaryKey(staffId) ;
        String wxEnterpriseId = staff.getWxEnterpriseId() ;
        WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId) ;
        if(null == qwDTO) {
            return ;
        }
        String wxUserId = staff.getWxUserId() ;
        if(qwDTO.needOpenUserIdDk()) {
            wxUserId = staff.getWxOpenUseId() ;
        }
        SecretSettingDTO secretSetting = secretSettingService.getSecretSetting(qwDTO.getWxEnterpriseId(), SecretTypeEnum.CUSTOMIZED_APP.getVal());
        if (null != secretSetting && StringUtils.isNotBlank(secretSetting.getSecretVal())) {
            UserDTO user = qywxUserApiService.getSelfWorkWxUser(qwDTO.getDkCorpid(), secretSetting.getSecretVal(), wxUserId, qwDTO.getUrlHost());
            logger.info("成员详情(代开)={}",JSON.toJSONString(user)) ;
            if(null != user && null != user.getDepartment()) {
                this.staffDepartChange(staff, wxEnterpriseId, user.getDepartment(),false); ;
            }
        }
	}
	
	public void staffDepartChange(TabHaobanStaff staff, String wxEnterpriseId, Integer[] departmentIds , boolean retryFlag) { 
	    //更新部门
        List<String> wxDepartIds = new ArrayList<>();
        for (Integer wDId : departmentIds) {
            wxDepartIds.add(wDId.toString());
        }
        if(CollectionUtils.isEmpty(wxDepartIds)) {
            return ;
        }
        //关联部门
        List<DepartmentDTO> departmentDTOList = departmentService.listDepartmentByWxDepartIds(wxEnterpriseId, wxDepartIds);
        if (CollectionUtils.isEmpty(departmentDTOList)) {
            logger.info("部门没有更新或同步：wxEnterpriseId={},wxDepartIds={}", wxEnterpriseId,wxDepartIds);
            if(retryFlag) {
                Map<String,Object> map = new HashMap<>() ;
                map.put("staffId", staff.getStaffId()) ;
                CommonMQDTO dto = new CommonMQDTO();
                dto.setType(2);
                dto.setParams(map);
                this.haobanCommonMQApiService.putCommonDelayMessage(dto, 180);
            }
            return;
        }

        //已存在部门
        List<TabHaobanStaffDepartmentRelated> hasRelation = this.listStaffDepartmentByStaffId(staff.getStaffId());
        Map<String, TabHaobanStaffDepartmentRelated> hasRelationMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(hasRelation)) {
            hasRelationMap = hasRelation.stream().collect(Collectors.toMap(TabHaobanStaffDepartmentRelated::getDepartmentId, tab -> tab));
        }

        //新增操作
        for (DepartmentDTO departmentDTO : departmentDTOList) {
            if (!hasRelationMap.containsKey(departmentDTO.getDepartmentId())) {
                StaffDepartmentRelatedDTO dto = new StaffDepartmentRelatedDTO();
                dto.setPhoneNumber(staff.getPhoneNumber());
                dto.setStaffId(staff.getStaffId());
                dto.setStaffName(staff.getStaffName());
                dto.setWxEnterpriseId(wxEnterpriseId);
                dto.setStatusFlag(1);
                dto.setDepartmentId(departmentDTO.getDepartmentId());
                dto.setNationCode(staff.getNationCode());
                this.add(dto);
            }
        }
        //删除操作
        Set<String> newDepartIds = departmentDTOList.stream().map(DepartmentDTO::getDepartmentId).collect(Collectors.toSet());
        Set<String> hasDepartIds = hasRelationMap.keySet();
        Sets.SetView<String> delDepartIds = Sets.difference(hasDepartIds, newDepartIds);
        Sets.SetView<String> updateDepartIds = Sets.intersection(newDepartIds, hasDepartIds);//交集
        logger.info("删除部门：{}", JSONObject.toJSONString(delDepartIds));
        if (CollectionUtils.isNotEmpty(delDepartIds)) {
            for (String delDepartId : delDepartIds) {
                TabHaobanStaffDepartmentRelated departmentRelated = hasRelationMap.get(delDepartId);
                if (null != departmentRelated) {
                    StaffDepartmentRelatedDTO relatedDTO = new StaffDepartmentRelatedDTO();
                    relatedDTO.setStaffDepartmentRelatedId(departmentRelated.getStaffDepartmentRelatedId());
                    this.del(relatedDTO);
                }
            }
        }

        if (CollectionUtils.isNotEmpty(updateDepartIds)) {
            for (String updateDeId : updateDepartIds) {
                TabHaobanStaffDepartmentRelated departmentRelated = hasRelationMap.get(updateDeId);
                if (null != departmentRelated) {
                    departmentRelated.setPhoneNumber(staff.getPhoneNumber());
                    departmentRelated.setStaffName(staff.getStaffName());
                    departmentRelated.setNationCode(staff.getNationCode());
                    departmentRelated.setUpdateTime(new Date());
                    this.update(departmentRelated);
                }
            }
        }
	}
}
