package com.gic.haoban.manage.web.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.gic.haoban.manage.api.dto.*;
import com.gic.haoban.manage.api.dto.qdto.TransferActiveCodeQDTO;
import com.gic.haoban.manage.api.dto.qdto.licence.LicenceOrderPageQDTO;
import com.gic.haoban.manage.api.service.*;
import com.gic.haoban.manage.web.log.LogRecordUserServiceImpl;
import com.gic.haoban.manage.web.qo.StaffListQO;
import com.gic.haoban.manage.web.qo.TransferActiveCodeQO;
import com.gic.haoban.manage.web.vo.*;
import com.gic.log.record.anno.GicLogRecord;
import com.gic.log.record.util.GicLogRecordCategoryEnum;
import com.gic.log.record.util.GicLogRecordEvaluationContext;
import com.gic.log.record.util.GicLogRecordOptTypeEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSON;
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.ClerkNewService;
import com.gic.clerk.api.service.ClerkService;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.ExcelUtils;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.enterprise.api.dto.EnterpriseSettingDTO;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.EnterpriseService;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.base.api.common.pojo.dto.WebLoginDTO;
import com.gic.haoban.common.utils.AuthWebRequestUtil;
import com.gic.haoban.common.utils.EntityUtil;
import com.gic.haoban.common.utils.HaobanResponse;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.manage.api.enums.ChannelCodeEnum;
import com.gic.haoban.manage.web.errCode.HaoBanErrCode;
import com.gic.haoban.manage.web.qo.StaffEditJsonQO;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.google.common.collect.Lists;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;


@RestController
public class StaffController extends WebBaseController {
    private static final Logger logger = LoggerFactory.getLogger(StaffController.class);

    @Autowired
    private StaffApiService staffApiService;
    @Autowired
    private DepartmentApiService departmentApiService;
    @Autowired
    private StaffDepartmentRelatedApiService staffDepartmentRelatedApiService;
    @Autowired
    private QywxUserApiService qywxUserApiService;
    @Autowired
    private WxEnterpriseApiService wxEnterpriseApiService;
    @Autowired
    private WxApplicationApiService wxApplicationApiService;
    @Autowired
    private ClerkService clerkService;
    @Autowired
    private ClerkNewService clerkNewService;
    @Autowired
    private StoreService storeService;
    @Autowired
    private StaffClerkRelationApiService staffClerkRelationApiService;
    @Autowired
    private WxEnterpriseRelatedApiService wxEnterpriseRelatedApiService;
    @Autowired
    private ClerkMainStoreRelatedApiService clerkMainStoreRelatedApiService;
    @Autowired
    private HaobanUserApiService haobanUserApiService;
    @Autowired
    private DealSyncOperationApiService dealSyncOperationApiService;
    @Autowired
    private EnterpriseService enterpriseService;
    @Autowired
    private WxEnterpriseActiveDataApiService wxEnterpriseActiveDataApiService;


    @RequestMapping("set-default-gicenterprise")
    public HaobanResponse updateDefaultGicEid(String enterpriseId) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String userId = login.getHanbaoUserId();
        this.haobanUserApiService.updateDefaultGicEid(userId, enterpriseId);
        return this.success(null);
    }

    @RequestMapping("staff-sel")
    public HaobanResponse staffSel(String staffId) {
        StaffDTO staff = staffApiService.selectById(staffId);
        List<StaffDepartmentRelatedDTO> list = staffApiService.listStaffDepartmentByStaffId(staffId);
        List<DepartmentDTO> departmentList = new ArrayList<DepartmentDTO>();
        for (StaffDepartmentRelatedDTO staffDepartmentRelatedDTO : list) {
            DepartmentDTO dto = departmentApiService.selectById(staffDepartmentRelatedDTO.getDepartmentId());
            departmentList.add(dto);

        }
        staff.setDepartmentList(departmentList);
        return resultResponse(HaoBanErrCode.ERR_1, staff);
    }

    /**
     * 分页查询员工列表
     */
    @RequestMapping("staff-list")
    public HaobanResponse staffList(@RequestBody StaffListQO qo) {
        logger.info("通讯录列表查询参数：{}",JSONObject.toJSONString(qo));
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        List<String> departmentIds = new ArrayList<>();
        DepartmentDTO departmentDTO = departmentApiService.selectById(qo.getDepartmentId());
        if (departmentDTO != null) {
            String parentDepartmentId = departmentDTO.getParentDepartmentId();
            if (!"0".equals(parentDepartmentId)) {
                departmentIds = departmentApiService.listSonDeptIdsByDepartmentId(qo.getDepartmentId(), wxEnterpriseId);
            }
        }
        //员工
        StaffListDTO dto = EntityUtil.changeEntityByJSON(StaffListDTO.class, qo);
        if(StringUtils.isNotBlank(qo.getClerkId())) {
            StaffClerkRelationDTO clerkRelationDTO = this.staffClerkRelationApiService.getByClerkId(qo.getClerkId()) ;
            if(null == clerkRelationDTO) {
                return resultResponse(HaoBanErrCode.ERR_1, PageUtil.getPageInfo(new Page<>()));
            }
            dto.setStaffId(clerkRelationDTO.getStaffId());
        }
        dto.setWxEnterpriseId(wxEnterpriseId);
        dto.setDepartmentIds(departmentIds);
        if (qo.getGetAllFlag() == 1){
            //续期订单需要查询所有数据
            BasePageInfo basePageInfo = new BasePageInfo();
            basePageInfo.setPageNum(1);
            basePageInfo.setPageSize(Integer.MAX_VALUE);
            dto.setPageInfo(basePageInfo);
        }
        dto.setLoginEnterpriseId(login.getEnterpriseId());
        Page<StaffDTO> page = staffApiService.pageStaff(dto);

        logger.info("pages={},totalPage={}", page.getCurrentPage(), page.getTotalPage());
        if(CollectionUtils.isNotEmpty(page.getResult())) {
            page.getResult().forEach(staff->{
                Integer activiveFlag = staff.getActiveFlag();
                Integer openConcatFlag = staff.getOpenConcatFlag();
                String remark ="" ;
                if (activiveFlag == 0) {
                    remark = "未激活";
                } else if (openConcatFlag == 0) {
                    remark = "未配置客户联系功能";
                }
                staff.setOwnerRemark(remark);
                
            });
        }
        return resultResponse(HaoBanErrCode.ERR_1, PageUtil.getPageInfo(page));
    }

    @RequestMapping("staff-edit")
    public HaobanResponse staffEdit(StaffDTO staffDTO, String departmentIds) {
        String staffId = staffDTO.getStaffId();
        StaffDTO staff = staffApiService.selectById(staffId);
        if (staff == null) {
            return resultResponse(HaoBanErrCode.ERR_10006);
        }
        String phoneNumber = staffDTO.getPhoneNumber();
        String nationcode = staffDTO.getNationCode();
        String wxEnterpriseId = staff.getWxEnterpriseId();
        StaffDTO old = staffApiService.selectByNationcodeAndPhoneNumber(wxEnterpriseId, nationcode, phoneNumber);
        if (old != null && !old.getStaffId().equals(staffId)) {
            return resultResponse(HaoBanErrCode.ERR_10005);
        }
        staffApiService.staffEdit(staffDTO, departmentIds);
        return resultResponse(HaoBanErrCode.ERR_1);
    }

    @RequestMapping("staff-invite")
    public HaobanResponse staffInvite(String staffIds) {
        if (StringUtils.isBlank(staffIds)) {
            return resultResponse(HaoBanErrCode.ERR_2);
        }
        String[] staffArr = staffIds.split(",");
        List<String> userArr = new ArrayList<>();
        String wxEnterpriseId = "";
        for (String staffId : staffArr) {
            StaffDTO staff = staffApiService.selectById(staffId);
            if (staff != null) {
                String userId = staff.getWxUserId();
                wxEnterpriseId = staff.getWxEnterpriseId();
                WxEnterpriseQwDTO qwDTO = wxEnterpriseApiService.getQwInfo(wxEnterpriseId);
                if (qwDTO.needOpenUserId3th()) {
                    userId = staff.getWxOpenUseId();
                }
                userArr.add(userId);
            }
        }
        WxApplicationDTO application = wxApplicationApiService.selectByWxEnterpriseIdAndApplicationType(wxEnterpriseId, 1);
        if (application != null) {
            qywxUserApiService.inviteUser(application.getCorpid(), application.getSiteId(), userArr);
        }
        return resultResponse(HaoBanErrCode.ERR_1);

    }

    @RequestMapping("staff-batch-edit-department")
    public HaobanResponse staffBatchEditDepartment(String params) {
        List<StaffEditJsonQO> list = JSON.parseArray(params, StaffEditJsonQO.class);
        for (StaffEditJsonQO staffEditJsonQO : list) {
            String staffDepartmentRelatedId = staffEditJsonQO.getStaffDepartmentRelatedId();
            String departmentIds = staffEditJsonQO.getCurrDepartmentIds();
            StaffDepartmentRelatedDTO related = staffDepartmentRelatedApiService.getByStaffDepartmentRelatedId(staffDepartmentRelatedId);
            if (related != null) {
                StaffDTO staff = staffApiService.selectById(related.getStaffId());
                if (staff != null) {
                    staffApiService.staffEdit(staff, departmentIds);
                }
            }
        }
        return resultResponse(HaoBanErrCode.ERR_1);
    }


    @RequestMapping("get-clerk-info")
    public HaobanResponse getClerkInfo(String clerkId) {
        StaffVO staffVO = new StaffVO();
        ClerkDTO clerk = clerkService.getClerkByClerkId(clerkId);
        if (clerk != null) {
            String storeId = clerk.getStoreId();
            StoreDTO storeDTO = storeService.getStore(storeId);
            staffVO.setStaffName(clerk.getClerkName());
            staffVO.setNationCode(clerk.getNationcode());
            staffVO.setPhoneNumber(clerk.getPhoneNumber());
            staffVO.setPosition(clerk.getPositionName());
            staffVO.setHeadImg(clerk.getHeadImgUrl());
            staffVO.setDepartmentName(storeDTO == null ? "" : storeDTO.getStoreName());
        }
        return resultResponse(HaoBanErrCode.ERR_1, staffVO);
    }

    @RequestMapping("get-staff-info")
    public HaobanResponse getStaffInfo(String staffId) {
        StaffVO staffVO = new StaffVO();
        StaffDTO staff = staffApiService.selectById(staffId);
        if (staff != null) {
            List<StaffDepartmentRelatedDTO> list = staffDepartmentRelatedApiService.listByStaffId(staffId);
            staffVO.setStaffName(staff.getStaffName());
            staffVO.setNationCode(staff.getNationCode());
            staffVO.setPhoneNumber(staff.getPhoneNumber());
            staffVO.setPosition(staff.getPostion());
            staffVO.setHeadImg(staff.getHeadImg());
            if (CollectionUtil.isNotEmpty(list)) {
                String departmentId = list.get(0).getDepartmentId();
                DepartmentDTO departmentDTO = departmentApiService.selectById(departmentId);
                if (departmentDTO != null) {
                    staffVO.setDepartmentName(departmentDTO.getDepartmentName());
                }
            }
        }
        return resultResponse(HaoBanErrCode.ERR_1, staffVO);
    }

    /**
     * 成员关联关系接口
     *
     * @param staffId
     * @return
     */
    @RequestMapping("staff-clerk-relation")
    public HaobanResponse staffClerkList(String staffId) {
        StaffDTO staff = staffApiService.selectById(staffId);
        if (staff == null) {
            return resultResponse(HaoBanErrCode.ERR_10007);
        }
        List<StaffClerkInfoDTO> retList = staffClerkRelationApiService.listBindDetailByStaffId(staffId);
        if (CollectionUtils.isEmpty(retList)) {
            return resultResponse(HaoBanErrCode.ERR_1);
        }
        ClerkMainStoreRelatedDTO mainStoreRelatedDTO = clerkMainStoreRelatedApiService.getWxEnterpriseIdAndStaffId(staff.getWxEnterpriseId(), staffId);
        for (StaffClerkInfoDTO dto : retList) {
            if (mainStoreRelatedDTO != null) {
                String storeId = dto.getStoreId();
                if (StringUtils.isNotBlank(storeId) && storeId.equals(mainStoreRelatedDTO.getStoreId())) {
                    dto.setMainStoreFlag(1);
                } else {
                    dto.setMainStoreFlag(0);
                }
            }
            if (dto.getManageFlag() != null && dto.getManageFlag() == 1) {
                dto.setManageStoreCount(staffApiService.getCountHaoBanStoreIdsByClerkId(dto.getClerkId(), staff.getWxEnterpriseId()).getStoreCount());
            }
        }
        return resultResponse(HaoBanErrCode.ERR_1, retList);
    }

    /**
     * 成员关联关系接口
     *
     * @param clerkId
     * @return
     */
    @RequestMapping("del-clerk-relation")
    public HaobanResponse delStaffClerkList(String clerkId) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        boolean b = staffClerkRelationApiService.unbindByStaffAndClerkId(login.getClerkId(), clerkId, ChannelCodeEnum.ADMIN_UNBIND.getCode(),login.getWxEnterpriseId());
        return resultResponse(HaoBanErrCode.ERR_1, b);
    }

    /**
     * 成员关联关系搜索接口
     *
     * @param search
     * @return
     */
    @RequestMapping("search-clerk-relation")
    public HaobanResponse staffClerkSearch(String search, Integer manageFlag) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        String enterpriseId = login.getEnterpriseId();
        if (null == wxEnterpriseId) {
            return resultResponse(HaoBanErrCode.ERR_4);
        }
        List<EnterpriseDetailDTO> list = wxEnterpriseRelatedApiService.listEnterpriseByWxEnterpriseId(wxEnterpriseId);
        if (CollectionUtil.isEmpty(list)) {
            return resultResponse(HaoBanErrCode.ERR_10010);
        }
        List<String> enterpriseIds = list.stream().filter(dto -> {
            boolean over = wxEnterpriseApiService.haobanIsStop(dto.getEnterpriseId());
            return !over;
        }).map(EnterpriseDetailDTO::getEnterpriseId).collect(Collectors.toList());

        List<String> storeIds = wxEnterpriseRelatedApiService.listStoreIdByWxEnterpriseId(wxEnterpriseId);
        if (CollectionUtils.isEmpty(storeIds)) {
            logger.info("没有权限门店");
            return resultResponse(HaoBanErrCode.ERR_1);
        }
        logger.info("好办门店数={},wxEnterpriseId={},enterpriseIds={}", storeIds.size(), wxEnterpriseId, enterpriseIds);
        List<ClerkDTO> clerkDTOList = new ArrayList<>();
        if (manageFlag != null && manageFlag == 1) {
            clerkDTOList = clerkService.listClerkEnableHaoban(enterpriseIds, search);
        } else {
            clerkDTOList = clerkNewService.listClerkByEnterpriseIdAndSearchAndClerkType(enterpriseIds, storeIds, search);
        }
        List<ClerkInfoVo> retList = EntityUtil.changeEntityListByJSON(ClerkInfoVo.class, clerkDTOList);
        if (CollectionUtils.isNotEmpty(retList)) {
            logger.info("导购数量={}", retList.size());
            List<String> clerkIds = retList.stream().map(ClerkInfoVo::getClerkId).collect(Collectors.toList());
            List<StaffClerkRelationDTO> dtos = new ArrayList<>();
            if (manageFlag != null && manageFlag == 1) {
                dtos = staffClerkRelationApiService.listByClerkIdsWxEnterpriseId(clerkIds, wxEnterpriseId);
            } else {
                dtos = staffClerkRelationApiService.listByClerkIds(clerkIds);
            }
            if (CollectionUtils.isNotEmpty(dtos)) {
                Map<String, StaffClerkRelationDTO> hasRelationClerkIds = dtos.stream().collect(Collectors.toMap(StaffClerkRelationDTO::getClerkId, mid -> mid));
                retList.forEach(clerkInfoVo -> {
                    if (hasRelationClerkIds.containsKey(clerkInfoVo.getClerkId())) {
                        clerkInfoVo.setRelationStatus(1);
                        StaffDTO staffDTO = staffApiService.selectById(hasRelationClerkIds.get(clerkInfoVo.getClerkId()).getStaffId());
                        if (staffDTO != null) {
                            clerkInfoVo.setStaffName(staffDTO.getStaffName());
                            clerkInfoVo.setStaffId(staffDTO.getStaffId());
                        }
                    }
                    StoreDTO store = storeService.getStore(clerkInfoVo.getStoreId());
                    if (null != store && store.getStatus() != -3) {
                        clerkInfoVo.setStoreName(store.getStoreName());
                    }
                });
                if (manageFlag == null || manageFlag != 1) {
                    retList = retList.stream().filter(o->StringUtils.isNotEmpty(o.getStoreName())).collect(Collectors.toList()) ;
                }
            }
        }
        if(null != login.getSuperAdmin() && login.getSuperAdmin()==1 && manageFlag == 1) {
            ClerkDTO superClerk = this.clerkService.getSuperAdminByEnterpriseId(enterpriseId) ;
            if(superClerk.getPhoneNumber().contains(search) || superClerk.getClerkCode().equals(search)) {
                superClerk.setClerkName("超级管理员");
                ClerkInfoVo superVO = EntityUtil.changeEntityByJSON(ClerkInfoVo.class, superClerk) ;
                // 判断是否有有关联
                if(CollectionUtils.isNotEmpty(staffClerkRelationApiService.listByClerkIds(Arrays.asList(superClerk.getClerkId())))) {
                    superVO.setRelationStatus(1);
                }
                retList.add(superVO);
            }
        }
        return resultResponse(HaoBanErrCode.ERR_1, retList);
    }

    /**
     * 新建关联
     *
     * @param staffId
     * @return
     */
    @RequestMapping("add-clerk-relation")
    public HaobanResponse staffClerkSearch(String staffId, String clerkId, Integer manageFlag) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        if (StringUtils.isAnyBlank(staffId, clerkId)) {
            return resultResponse(HaoBanErrCode.ERR_2);
        }
        StaffDTO staffDTO = staffApiService.selectById(staffId);
        if (null == staffDTO) {
            return resultResponse(HaoBanErrCode.ERR_10007);
        }
        ClerkDTO clerkDTO = clerkService.getClerkByClerkId(clerkId);
        if (null == clerkDTO) {
            return resultResponse(HaoBanErrCode.ERR_5);
        }
        StaffClerkRelationDTO relationDTO = new StaffClerkRelationDTO();
        relationDTO.setClerkCode(clerkDTO.getClerkCode());
        relationDTO.setClerkId(clerkId);
        relationDTO.setStaffId(staffId);
        relationDTO.setEnterpriseId(clerkDTO.getEnterpriseId());
        relationDTO.setStoreId(clerkDTO.getStoreId());
        relationDTO.setWxEnterpriseId(staffDTO.getWxEnterpriseId());
        relationDTO.setManageFlag(manageFlag);

        ServiceResponse response = staffClerkRelationApiService.bindStaffClerk(relationDTO, login.getClerkId(), ChannelCodeEnum.ADMIN_BIND.getCode());
        logger.info("返回信息：{}", JSONObject.toJSONString(response));
        if (response.isSuccess()) {
            return resultResponse(HaoBanErrCode.ERR_1);
        } else {
            HaoBanErrCode errDefine = HaoBanErrCode.ERR_DEFINE;
            errDefine.setMsg(response.getMessage());
            return resultResponse(errDefine);
        }
    }

    /**
     * 绑定日志
     *
     * @return
     */
    @RequestMapping("staff-clerk-bind-log")
    public HaobanResponse bindLogs(String search, @RequestParam(defaultValue = "-1") Integer optType, BasePageInfo qo) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String enterpriseId = login.getEnterpriseId();
        Page<StaffClerkBindLogDetailDTO> page = staffClerkRelationApiService.pageStaffClerkBindLog(login.getWxEnterpriseId(), search, enterpriseId, optType, qo);
        return resultResponse(HaoBanErrCode.ERR_1, page);
    }

    /**
     * 是否展示区经 true是
     * @return
     */
    @RequestMapping("hasManagerFlag")
    public RestResponse hasManagerFlag() {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        List<EnterpriseDetailDTO> list = wxEnterpriseRelatedApiService.listEnterpriseByWxEnterpriseId(wxEnterpriseId);
        if (CollectionUtil.isEmpty(list)) {
            return RestResponse.failure(Convert.toStr(HaoBanErrCode.ERR_10010.getCode()),HaoBanErrCode.ERR_10010.getMsg());
        }
        List<String> enterpriseIds = list.stream().filter(dto -> {
            boolean over = wxEnterpriseApiService.haobanIsStop(dto.getEnterpriseId());
            return !over;
        }).map(EnterpriseDetailDTO::getEnterpriseId).collect(Collectors.toList());
        boolean flag = false ;
        if(CollectionUtils.isNotEmpty(enterpriseIds)) {
            for(String eid : enterpriseIds) {
                EnterpriseSettingDTO enterpriseSetting =  enterpriseService.getEnterpriseSettingByEnterpriseId(eid) ;
                if (enterpriseSetting.getEnableAccessControl() != null && enterpriseSetting.getEnableAccessControl() == 1) {
                    flag = true ;
                    break ;
                }
            }
        }
        return RestResponse.successResult(flag);
    }

    /**
     * @return 返回值类型: <pre>
     * @author 作者: qwm
     * @date 时间: 2020年12月18日 上午11:11:35 <pre>
     * @Description 会员导出
     */
    @RequestMapping("staff-export")
    public HaobanResponse staffExport(HttpServletRequest request, HttpServletResponse response,String departmentId, Integer activeFlag, Integer relationFlag,
                                      String keyWord, String permitState,BasePageInfo pageInfo,@RequestParam(defaultValue = "create_time") String sortField,
                                      @RequestParam(defaultValue = "desc") String sortType,String enterpriseIdParam,String startTime,String endTime ,String clerkId) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        if(StringUtils.isBlank(departmentId)){
            DepartmentDTO dto = this.departmentApiService.getRootByEnterpriseId(wxEnterpriseId) ;
            if(null == dto) {
                return new HaobanResponse(-1,"根部门异常,请重新同步通讯录") ;
            }
            departmentId = dto.getDepartmentId() ;
        }
        List<String> departmentIdSet = new ArrayList<>();
        departmentIdSet.add(departmentId);
        List<DepartmentDTO> relationList = departmentApiService.listSonByDepartmentIds(departmentIdSet, wxEnterpriseId);
        Map<String, DepartmentDTO>  departmentMap = relationList.stream().collect(Collectors.toMap(DepartmentDTO::getDepartmentId, s -> s));
        List<String> departmentIds ;
        departmentIds = relationList.stream().map(DepartmentDTO::getDepartmentId).collect(Collectors.toList());
        List<StaffDTO> staffAllList = Lists.newArrayListWithCapacity(5000);
        StaffListDTO dto = new StaffListDTO();
        dto.setWxEnterpriseId(wxEnterpriseId);
        dto.setDepartmentIds(departmentIds);
        dto.setDepartmentId(departmentId);
        dto.setActiveFlag(activeFlag);
        dto.setRelationFlag(relationFlag);
        dto.setKeyWord(keyWord);
        dto.setPermitState(permitState);
        dto.setSortField(sortField);
        dto.setSortType(sortType);
        dto.setEnterpriseIdParam(enterpriseIdParam);
        dto.setStartTime(startTime);
        dto.setEndTime(endTime);
        if(StringUtils.isNotBlank(clerkId)) {
            StaffClerkRelationDTO clerkRelationDTO = this.staffClerkRelationApiService.getByClerkId(clerkId) ;
            if(null == clerkRelationDTO) {
                return resultResponse(HaoBanErrCode.ERR_1, PageUtil.getPageInfo(new Page<>()));
            }
            dto.setStaffId(clerkRelationDTO.getStaffId());
        }
        pageInfo.setPageSize(Integer.MAX_VALUE);
        int pageNum = 1;
        while (true) {
            pageInfo.setPageNum(pageNum);
            dto.setPageInfo(pageInfo);
            Page<StaffDTO> page = staffApiService.pageStaff(dto);
            List<StaffDTO> list = page.getResult();
            if (CollectionUtils.isEmpty(list)) {
                break;
            }
            staffAllList.addAll(list);
            pageNum++;
        }
        List<StaffExportVO> voList = new ArrayList<>();
        //针对多个商户使用一个企微时，导出所属商户名称
        Boolean flag=false;
        List<WxEnterpriseRelatedDTO> result = staffApiService.getWxEnterpriseRelatedList(wxEnterpriseId).getResult();
        if (CollUtil.isNotEmpty(result) && result.size()>1){
            flag = true;
        }
        for (StaffDTO staffDTO : staffAllList) {
            StaffExportVO vo = new StaffExportVO();
            vo.setStaffId(staffDTO.getStaffId());
            vo.setPhoneNumber(staffDTO.getPhoneNumber());
            vo.setStaffName(staffDTO.getStaffName());
            vo.setPosition(staffDTO.getPostion());
            vo.setDepartmentName(departmentMap.get(staffDTO.getDepartmentIds()) == null ? null : departmentMap.get(staffDTO.getDepartmentIds()).getDepartmentName());
            vo.setRelationFlag((Objects.isNull(staffDTO.getRelationFlag()) || staffDTO.getRelationFlag() == 0) ? "未关联" : "已关联");
            vo.setWxUserId(staffDTO.getWxUserId());
            vo.setWxOpenUseId(staffDTO.getWxOpenUseId());
            vo.setActiveTime(staffDTO.getActiveTime() == null ? null : DateUtil.dateToStr(staffDTO.getActiveTime(),DateUtil.FORMAT_DATETIME_19));
            vo.setExpireTime(staffDTO.getExpireTime() == null ? null : DateUtil.dateToStr(staffDTO.getExpireTime(),DateUtil.FORMAT_DATETIME_19));
            vo.setPermitState(staffDTO.getPermitState());
            if (flag){
                List<String> enterpriseNameList = staffDTO.getEnterpriseNameList();
                if (CollUtil.isNotEmpty(enterpriseNameList)){
                    String enterpriseName = String.join(",", enterpriseNameList);
                    vo.setEnterpriseName(enterpriseName);
                }else {
                    vo.setEnterpriseName("无归属");
                }
            }
            voList.add(vo);
        }
        //拼接导购信息
        WxEnterpriseDTO enterprise = wxEnterpriseApiService.getOne(wxEnterpriseId);
        String wxEnterpriseName = "";
        if (enterprise != null) {
            wxEnterpriseName = enterprise.getCorpName();
        }
        mergeClerkInfo(voList, wxEnterpriseId);
        String fileName = wxEnterpriseName + "通讯录" + DateUtil.dateToStr(new Date(), DateUtil.FORMAT_DATE_8);
        List<String> titleList =Lists.newArrayList("姓名", "职务", "部门", "手机号", "关联状态", "关联导购","成员明文userid");
        List<String> fileList = Lists.newArrayList("staffName", "position", "departmentName", "phoneNumber", "relationFlag", "clerkName","wxUserId");
        if (flag){
            titleList.add("所属商户");
            fileList.add("enterpriseName");
        }
        //针对未升级好办独立应用的企业，导出表格增加导出字段：成员明文userid、成员加密userid、许可状态、许可激活时间、许可到期时间
        if(enterprise != null && enterprise.getWxSecurityType() != 5){
            titleList.add("许可状态");
            titleList.add("许可激活时间");
            titleList.add("许可到期时间");
            fileList.add("wxOpenUseId");
            fileList.add("status");
            fileList.add("activeTime");
            fileList.add("expireTime");
        }
        try {
            ExcelUtils.xls(response, request, fileName, voList, fileList, titleList);
        } catch (Exception e) {
            logger.info("异常",e);
            logger.info("导出失败");
        }
        return null;
    }

    private void mergeClerkInfo(List<StaffExportVO> list, String wxEnterpriseId) {
        BasePageInfo pageInfoRelation = new BasePageInfo();
        int pageSizeRelation = 1000;
        int pageNumRelation = 1;
        pageInfoRelation.setPageNum(pageNumRelation);
        pageInfoRelation.setPageSize(pageSizeRelation);
        Page<StaffClerkRelationDTO> bindPage = staffClerkRelationApiService.pageByWxEnterpriseId(wxEnterpriseId, pageInfoRelation);
        List<StaffClerkRelationDTO> bindList = bindPage.getResult();
        Set<String> clerkIdList = bindList.stream().map(StaffClerkRelationDTO::getClerkId).collect(Collectors.toSet());
        List<ClerkDTO> clerkList = clerkService.getClerkByClerkIds(clerkIdList);
        while (bindPage.getCurrentPage() < bindPage.getTotalPage()) {
            pageNumRelation++;
            pageInfoRelation.setPageNum(pageNumRelation);
            bindPage = staffClerkRelationApiService.pageByWxEnterpriseId(wxEnterpriseId, pageInfoRelation);
            List<StaffClerkRelationDTO> sonList = bindPage.getResult();
            Set<String> clerkSonIdList = sonList.stream().map(StaffClerkRelationDTO::getClerkId).collect(Collectors.toSet());
            List<ClerkDTO> sonClerkList = clerkService.getClerkByClerkIds(clerkSonIdList);
            if (CollectionUtils.isNotEmpty(sonClerkList)) {
                clerkList.addAll(sonClerkList);
            }
            if (CollectionUtils.isNotEmpty(sonList)) {
                bindList.addAll(sonList);
            }
        }

        Map<String, List<StaffClerkRelationDTO>> bindMap = bindList.stream().collect(Collectors.groupingBy(StaffClerkRelationDTO::getStaffId));
        Map<String, ClerkDTO> clerkMap = clerkList.stream().collect(Collectors.toMap(ClerkDTO::getClerkId, s -> s, (v1, v2) -> v2));
        for (StaffExportVO staffDTO : list) {
            List<StaffClerkRelationDTO> relationList = bindMap.get(staffDTO.getStaffId());
            if (CollectionUtils.isNotEmpty(relationList)) {
                StringBuffer clerkName = new StringBuffer();
                for (StaffClerkRelationDTO staffClerkRelationDTO : relationList) {
                    ClerkDTO clerk = clerkMap.get(staffClerkRelationDTO.getClerkId());
                    if (clerk != null) {
                        clerkName.append(clerk.getClerkName()).append("(").append(clerk.getClerkCode()).append(")").append(",");
                    }
                }
                if (StringUtils.isNoneBlank(clerkName.toString())) {
                    clerkName = new StringBuffer(clerkName.substring(0, clerkName.length() - 1));
                }
                staffDTO.setClerkName(clerkName.toString());
            }
        }
    }


    /**
     * 通讯录同步
     *
     * @return
     */
    @RequestMapping("sync-qywx")
    public Object syncQywx() {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        WxEnterpriseDTO enterpriseDTO = this.wxEnterpriseApiService.getOne(wxEnterpriseId);
        if (enterpriseDTO != null) {
            String taskId = dealSyncOperationApiService.createQywxTask(wxEnterpriseId, "后门同步企业微信架构", login.getClerkId(), "后门同步企业微信架构");
            if (StringUtils.isBlank(taskId)) {
                return this.fail("通讯录正在同步中") ; //resultResponse(HaoBanErrCode.ERR_0, false);
            }
            String ret = dealSyncOperationApiService.dealQywxDepartment(taskId, wxEnterpriseId);
            if (null != ret) {
                return resultResponse(HaoBanErrCode.ERR_0, ret, null, null);
            }
        }
        return resultResponse(HaoBanErrCode.ERR_1);
    }

    /**
     * 通讯录许可数据总览
     *
     */
    @RequestMapping("staff-active-data")
    public RestResponse<StaffActiveDataVO> getStaffActiveData() {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        ServiceResponse<StaffActiveDataDTO> StaffActiveDataDTO = wxEnterpriseActiveDataApiService.getWxEnterpriseActiveDataByWxEnterpriseId(wxEnterpriseId);
        StaffActiveDataVO staffActiveDataVO = JSONObject.parseObject(JSONObject.toJSONString(StaffActiveDataDTO.getResult()), StaffActiveDataVO.class);
        return RestResponse.successResult(staffActiveDataVO);
    }
    /**
     * 通讯录许可转移
     */
    @RequestMapping("staff-active-transfer")
    @GicLogRecord(value = "${#logValue}", category = GicLogRecordCategoryEnum.HB_TXL, optType = GicLogRecordOptTypeEnum.HB_1003_01, userFunc = LogRecordUserServiceImpl.class, optPage = "好办通讯录许可转移")
    public RestResponse transferActiveCode(@RequestBody List<TransferActiveCodeQO> transferActiveCodeQOList) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        List<TransferActiveCodeQDTO> transferActiveCodeQDTOList = JSONArray.parseArray(JSONObject.toJSONString(transferActiveCodeQOList), TransferActiveCodeQDTO.class);
        ServiceResponse<TransferActiveCodeDTO> transferActiveCodeDTOServiceResponse = staffApiService.batchTransferLicense(transferActiveCodeQDTOList, wxEnterpriseId);
        //保存操作日志
        TransferActiveCodeDTO result = transferActiveCodeDTOServiceResponse.getResult();
        if (null != result) {
            String logs = result.logRecord();
            GicLogRecordEvaluationContext.putAttribute("logValue", logs);
        }
        return RestResponse.successResult(transferActiveCodeDTOServiceResponse);
    }

    /**
     * 查询企业微信对应的所有商户品牌信息
     *
     */
    @RequestMapping("get-wxEnterprise-related-list")
    public RestResponse<List<WxEnterpriseRelatedVO>> getWxEnterpriseRelatedList() {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        ServiceResponse<List<WxEnterpriseRelatedDTO>> response = staffApiService.getWxEnterpriseRelatedList(wxEnterpriseId);
        List<WxEnterpriseRelatedVO> vo = JSONArray.parseArray(JSONObject.toJSONString(response.getResult()), WxEnterpriseRelatedVO.class);
        if (CollUtil.isEmpty(vo)){
            return RestResponse.successResult(new ArrayList<>());
        }
        return RestResponse.successResult(vo);
    }

    /**
     * 批量分配成员许可码
     * @param staffIds
     * @return
     */
    @RequestMapping("staff-active-allocation")
    public RestResponse<StaffActiveAllocationVO> staffActiveAllocation(String staffIds) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        ServiceResponse<StaffActiveAllocationDTO> response = staffApiService.staffActiveAllocation(wxEnterpriseId, staffIds);
        if(response.isSuccess()){
            StaffActiveAllocationDTO dto = response.getResult();
            StaffActiveAllocationVO result = JSONObject.parseObject(JSONObject.toJSONString(dto), StaffActiveAllocationVO.class);
            return RestResponse.successResult(result);
        }
        return RestResponse.failure(response.getCode(),response.getMessage());
    }

}
