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

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.commons.util.EntityUtil;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.base.api.common.Constant;
import com.gic.haoban.base.api.common.ServiceResponse;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.DepartmentDTO;
import com.gic.haoban.manage.api.dto.DepartmentShortDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseDTO;
import com.gic.haoban.manage.api.service.DepartmentApiService;
import com.gic.haoban.manage.api.service.StaffApiService;
import com.gic.haoban.manage.api.service.StaffDepartmentRelatedApiService;
import com.gic.haoban.manage.service.dao.mapper.DepartmentMapper;
import com.gic.haoban.manage.service.entity.TabHaobanDepartment;
import com.gic.haoban.manage.service.entity.TabHaobanStaffDepartmentRelated;
import com.gic.haoban.manage.service.entity.TabHaobanSyncErrorLog;
import com.gic.haoban.manage.service.service.*;
import com.gic.redis.data.util.RedisUtil;
import com.gic.wechat.api.service.qywx.QywxDepartmentApiService;
import com.github.pagehelper.PageHelper;
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.stereotype.Service;

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

@Service
public class DepartmentApiServiceImpl implements DepartmentApiService {

    private static Logger logger = LoggerFactory.getLogger(DepartmentApiServiceImpl.class);

    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private StaffDepartmentRelatedService staffDepartmentService;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private com.gic.enterprise.api.service.DepartmentService gicDepartmentService;
    @Autowired
    private QywxDepartmentApiService qywxDepartmentApiService;
    @Autowired
    private WxEnterpriseService wxEnterpriseService;
    @Autowired
    private StaffApiService staffApiService;
    @Autowired
    private StaffDepartmentRelatedApiService staffDepartmentRelatedApiService;
    @Autowired
    private SyncErrorLogService syncErrorLogService;
    @Autowired
    private SecretSettingService secretSettingService;


    @Override
    public List<DepartmentDTO> listByParentId(String parentId) {
        List<TabHaobanDepartment> list = departmentService.listByParentId(parentId);

        return EntityUtil.changeEntityListByJSON(DepartmentDTO.class, list);
    }

    @Override
    public DepartmentDTO selectById(String departmentId) {
        TabHaobanDepartment tab = departmentService.selectById(departmentId);
        return EntityUtil.changeEntityByJSON(DepartmentDTO.class, tab);
    }

    @Override
    public ServiceResponse wxCallBackDel(String departmentId) {
        ServiceResponse hr = new ServiceResponse();
        hr.setCode(1);

        List<TabHaobanDepartment> list = departmentService.listByParentId(departmentId);
        logger.info("【部门删除】list.size={}", list.size());
        if (!list.isEmpty()) {
            hr.setCode(0);
            hr.setMessage("存在子部门，删除部门失败");
            return hr;
        }

        List<TabHaobanStaffDepartmentRelated> staffList = staffDepartmentService.listByDepartmentId(departmentId);
        logger.info("【部门删除】staffList.size={}", staffList.size());
        if (!staffList.isEmpty()) {
            hr.setCode(0);
            hr.setMessage("存在成员，删除部门失败");
            return hr;
        }
        departmentService.del(departmentId);
        return hr;
    }

    @Override
    public DepartmentDTO selectByRelatedId(String relatedId) {
        TabHaobanDepartment tab = departmentService.selectByRelatedId(relatedId);
        return EntityUtil.changeEntityByJSON(DepartmentDTO.class, tab);
    }

    @Override
    public ServiceResponse wxCallBackrecycle(String departmentId) {
        ServiceResponse hr = new ServiceResponse();
        hr.setCode(1);
        List<TabHaobanDepartment> list = departmentService.listByParentId(departmentId);
        logger.info("【部门删除】list.size={}", list.size());
        if (CollectionUtils.isNotEmpty(list)) {
            hr.setCode(0);
            hr.setMessage("存在子部门，删除部门失败");
            return hr;
        }
        List<TabHaobanStaffDepartmentRelated> staffList = staffDepartmentService.listByDepartmentId(departmentId);
        logger.info("【部门删除】staffList.size={}", staffList.size());
        if (CollectionUtils.isNotEmpty(staffList)) {
            hr.setCode(0);
            hr.setMessage("存在成员，删除部门失败");
            return hr;
        }
        departmentService.recycle(departmentId);
        return hr;
    }

    @Override
    public Page<DepartmentDTO> pageDepartmentByParams(BasePageInfo pageInfo, String wxEnterpriseId, String keyword,
                                                      Integer storeFlag, Integer recycleFlag) {
        PageHelper.startPage(pageInfo.getPageNum(), pageInfo.getPageSize());
        return PageUtil.changePageHelperToCurrentPage(departmentService.pageDepartmentByParams(wxEnterpriseId, keyword, storeFlag, recycleFlag), DepartmentDTO.class);
    }

    @Override
    public List<DepartmentDTO> listByDepartmentIds(List<String> departmentIds,
                                                   Integer storeFlag) {
        List<TabHaobanDepartment> list = departmentMapper.listByDepartmentIds(departmentIds, storeFlag);
        if (list == null) {
            return new ArrayList<DepartmentDTO>();
        }
        return EntityUtil.changeEntityListByJSON(DepartmentDTO.class, list);
    }

    @Override
    public List<DepartmentDTO> listByRelatedIds(List<String> relatedIds) {
        List<TabHaobanDepartment> list = departmentMapper.listByRelatedIds(relatedIds);
        if (list == null) {
            return new ArrayList<DepartmentDTO>();
        }
        return EntityUtil.changeEntityListByJSON(DepartmentDTO.class, list);
    }

    @Override
    public DepartmentDTO getRootByEnterpriseId(String wxEnterpriseId) {

        return departmentService.getRootByEnterpriseId(wxEnterpriseId);
    }

//    @Override
//    public List<DepartmentDTO> listStoreByWxEnterpriseId(String wxEnterpriseId) {
//        List<TabHaobanDepartment> list = departmentMapper.listStoreByWxEnterpriseId(wxEnterpriseId);
//        return EntityUtil.changeEntityListByJSON(DepartmentDTO.class, list);
//    }

    @Override
    public Page<DepartmentDTO> pageFullStoreByWxEnterpriseId(
            String wxEnterpriseId, String search, List<String> storeIds, int count, BasePageInfo pageInfo) {
        PageHelper.startPage(pageInfo.getPageNum(), pageInfo.getPageSize());
        if (CollectionUtil.isNotEmpty(storeIds) && StringUtils.isNotEmpty(search)) {
            return PageUtil.changePageHelperToCurrentPage(departmentMapper.pageFullStoreByWxEnterpriseId2(wxEnterpriseId, search, storeIds, count), DepartmentDTO.class);
        }
        return PageUtil.changePageHelperToCurrentPage(departmentMapper.pageFullStoreByWxEnterpriseId(wxEnterpriseId, search, storeIds, count), DepartmentDTO.class);
    }

    @Override
    public void syncGicStore(String fieldListString) {
        if (true) {
            return;
        }
    }

    @Override
    public void syncGicDepartment(String fieldListString) {


    }

    @Override
    public Page<DepartmentDTO> pageByParentId(String parentId, String keyword, BasePageInfo pageInfo) {
        PageHelper.startPage(pageInfo.getPageNum(), pageInfo.getPageSize());
        return PageUtil.changePageHelperToCurrentPage(departmentService.pageByParentId(parentId, keyword), DepartmentDTO.class);
    }

    @Override
    public List<DepartmentDTO> listByChainId(String chainId, String wxEnterpriseId) {
        List<TabHaobanDepartment> list = departmentService.listByChainId(chainId, wxEnterpriseId);
        return EntityUtil.changeEntityListByJSON(DepartmentDTO.class, list);
    }

    @Override
    public void initwxDepartment(String corpid, String contactSecret, String wxEnterpriseId) {
        logger.info("【同步企业微信】wxEnterpriseId={}", "init-enterprise-" + wxEnterpriseId);
        String key = "init-enterprise-" + wxEnterpriseId;
        if (RedisUtil.getCache(key) == null) {
            RedisUtil.setCache(key, 1, 60 * 60L);
            String taskId = StringUtil.randomUUID();
            List<com.gic.wechat.api.dto.qywx.DepartmentDTO> list = this.qywxDepartmentApiService.listSelfDepartment(corpid, contactSecret, null);
            logger.info("企业所有部门数据：{}", JSON.toJSONString(list));
            if (CollectionUtils.isNotEmpty(list)) {
                this.addAllDepartment(list, 0, wxEnterpriseId, corpid, contactSecret, taskId);
            }
        } else {
            RedisUtil.delCache(key);
        }
    }

    @Override
    public void syncWxDepartmentByParentMQ(String res) {
        JSONObject json = JSON.parseObject(res);
        Integer parentId = json.getInteger("parentId");
        String wxEnterpriseId = json.getString("wxEnterpriseId");
        String corpid = json.getString("corpid");
        String contactSecret = json.getString("contactSecret");
        String taskId = json.getString("taskId");
        List<com.gic.wechat.api.dto.qywx.DepartmentDTO> list = this.qywxDepartmentApiService.listSelfDepartment(corpid, contactSecret, parentId);
        List<com.gic.wechat.api.dto.qywx.DepartmentDTO> handerList = new ArrayList<>();
        if (parentId.equals(0)) {
            for (com.gic.wechat.api.dto.qywx.DepartmentDTO departmentDTO : list) {
                if (departmentDTO.getId() == 1) {
                    handerList.add(departmentDTO);
                    break;
                }
            }
        } else {
            for (com.gic.wechat.api.dto.qywx.DepartmentDTO departmentDTO : list) {
                if (departmentDTO.getParentid().equals(parentId)) {
                    handerList.add(departmentDTO);
                }
            }
        }
        if (parentId != 0) {
            TabHaobanDepartment parent = this.departmentService.getByWxId(parentId + "", wxEnterpriseId);
            if (parent == null) {
                TabHaobanSyncErrorLog tab = new TabHaobanSyncErrorLog();
                tab.setDataId(parentId + "");
                tab.setDataType(0);
                tab.setLogType(0);
                tab.setReason("父部门不存在");
                tab.setTaskId(taskId);
                tab.setWxEnterpriseId(wxEnterpriseId);
                syncErrorLogService.add(tab);
            }
        }
        logger.info("【mq同步】parentId={}", parentId);
    }

//    @Override
//    public boolean isInitLocked(String wxEnterpriseId) {
//        return RedisUtil.isLocked("init-enterprise-" + wxEnterpriseId);
//    }


    private void addAllDepartment(List<com.gic.wechat.api.dto.qywx.DepartmentDTO> list, Integer parentId,
                                  String wxEnterpriseId, String corpid, String contactSecret, String taskId) {
        logger.info("新增所有企微部门");
        int level = 1;
        String chainId = "0";
        String chainName = "0";
        String pId = "0";
        if (parentId != 0) {
            TabHaobanDepartment parent = this.departmentService.getByWxId(parentId + "", wxEnterpriseId);
            if (parent != null) {
                level = parent.getLevel() + 1;
                chainId = parent.getChainId() + Constant.ID_SEPARATOR + parent.getDepartmentId();
                chainName = parent.getChainName() + Constant.NAME_SEPARATOR + parent.getDepartmentName();
                pId = parent.getDepartmentId();
            }
        }
        for (com.gic.wechat.api.dto.qywx.DepartmentDTO departmentDTO : list) {
            try {
                if (parentId.equals(departmentDTO.getParentid())) {
                    TabHaobanDepartment exist = this.departmentService.getByWxId(departmentDTO.getId() + "", wxEnterpriseId);
                    logger.info("分组是否存在：{}", JSON.toJSONString(exist));
                    if (exist == null) {
                        com.gic.haoban.manage.api.dto.DepartmentDTO dto = new com.gic.haoban.manage.api.dto.DepartmentDTO();
                        dto.setDepartmentName(departmentDTO.getName());
                        dto.setLevel(level);
                        dto.setWxEnterpriseId(wxEnterpriseId);
                        dto.setWxDepartmentId(departmentDTO.getId() + "");
                        dto.setParentDepartmentId(pId);
                        dto.setChainId(chainId);
                        dto.setChainName(chainName);
                        dto.setSort(departmentDTO.getOrder());
                        dto.setIsStore(0);
                        this.departmentService.add(dto);
                    }
                }
            } catch (Exception e) {
                TabHaobanSyncErrorLog tab = new TabHaobanSyncErrorLog();
                tab.setDataId(departmentDTO.getId() + "");
                tab.setDataType(0);
                tab.setLogType(0);
                tab.setReason(e.getMessage());
                tab.setTaskId(taskId);
                tab.setWxEnterpriseId(wxEnterpriseId);
                syncErrorLogService.add(tab);
            }
            this.addAllDepartment(list, departmentDTO.getId(), wxEnterpriseId, corpid, contactSecret, taskId);
            this.staffApiService.initWxUser(corpid, contactSecret, wxEnterpriseId, departmentDTO.getId(), taskId);
        }
    }

    @Override
    public Integer departmentRecycleCount(String wxEnterpriseId) {
        return departmentService.departmentRecycleCount(wxEnterpriseId);
    }

    @Override
    public boolean hasSonNode(String departmentId) {
        int departmentCount = departmentService.countByDepartment(departmentId);
        if (departmentCount > 0) {
            return true;
        }
        return false;
    }

    @Override
    @Deprecated
    public ServiceResponse gicDel(String departmentId) {
        ServiceResponse hr = new ServiceResponse();
        hr.setCode(1);
        List<TabHaobanDepartment> list = departmentService.listByParentId(departmentId);
        logger.info("【部门删除】list.size={}", list.size());
        if (!list.isEmpty()) {
            hr.setCode(0);
            hr.setMessage("存在子部门，删除部门失败");
            //return hr;
            TabHaobanDepartment department = departmentService.selectById(departmentId);
            if (department != null) {
                department.setGicDelFlag(1);
            }
            departmentMapper.updateByPrimaryKeySelective(department);
        }

        List<TabHaobanStaffDepartmentRelated> staffList = staffDepartmentService.listByDepartmentId(departmentId);
        logger.info("【部门删除】staffList.size={}", staffList.size());
        if (!staffList.isEmpty()) {
            hr.setCode(0);
            hr.setMessage("存在成员，删除部门失败");
            //return hr;
            TabHaobanDepartment department = departmentService.selectById(departmentId);
            if (department != null) {
                department.setGicDelFlag(1);
            }
            departmentMapper.updateByPrimaryKeySelective(department);
        }
        //调微信的删除接口
        TabHaobanDepartment department = departmentService.selectById(departmentId);
        WxEnterpriseDTO enterpriseDTO = wxEnterpriseService.selectById(department.getWxEnterpriseId());
        departmentService.del(departmentId);
        return hr;

    }


//    @Override
//    public ServiceResponse<List<DepartmentDTO>> listStoreListByStaffId(String staffId) {
//        ServiceResponse<List<DepartmentDTO>> rer = new ServiceResponse<List<DepartmentDTO>>();
//        List<StaffDepartmentRelatedDTO> relateList = staffDepartmentRelatedApiService.listByStaffId(staffId);
//        if (CollectionUtils.isEmpty(relateList)) {
//            logger.info("没有部分显示:{}", staffId);
//            return rer;
//        }
//        List<String> departmentIds = relateList.stream().map(dto -> dto.getDepartmentId()).collect(Collectors.toList());
//        List<DepartmentDTO> departmentList = listByDepartmentIds(departmentIds, 1);
//        rer.setResult(departmentList);
//        return rer;
//    }

    @Override
    public Integer totalStoreCountByEnterpriseId(String wxEnterpriseId) {
        return departmentService.totalStoreCountByEnterpriseId(wxEnterpriseId);
    }

    @Override
    public List<DepartmentDTO> listSonByDepartmentIds(List<String> departmentIdList, String wxEnterpriseId) {
        List<TabHaobanDepartment> list = new ArrayList<>();
        for (String departmentId : departmentIdList) {
            String chainId = "";
            TabHaobanDepartment department = departmentService.selectById(departmentId);
            if (department != null) {
                chainId = department.getChainId() + Constant.ID_SEPARATOR + departmentId;
            }
            list.add(department);
            if (StringUtils.isNotBlank(chainId)) {
                List<TabHaobanDepartment> tabList = departmentService.listByChainId(chainId, wxEnterpriseId);
                list.addAll(tabList);
            }
        }
        return EntityUtil.changeEntityListByJSON(DepartmentDTO.class, list);
    }

    @Override
    public List<DepartmentShortDTO> searchDepartment(String search, String wxEnterpriseId) {
        return departmentService.searchDepartment(search, wxEnterpriseId);
    }

    @Override
    public List<DepartmentShortDTO> listAllDepartment(String wxEnterpriseId) {
        List<DepartmentShortDTO> list = departmentService.listAllDepartment(wxEnterpriseId);
        return list;
    }

    @Override
    public List<String> listSonDeptIdsByDepartmentId(String departmentId, String wxEnterpriseId) {
        List<String> list = new ArrayList<>();
        String chainId = "";
        TabHaobanDepartment department = departmentService.selectById(departmentId);
        if (department != null) {
            chainId = department.getChainId() + Constant.ID_SEPARATOR + departmentId;
        }
        list.add(departmentId);
        if (StringUtils.isNotBlank(chainId)) {
            List<TabHaobanDepartment> tabList = departmentService.listByChainId(chainId, wxEnterpriseId);
            List<String> departmentIds = tabList.stream().map(TabHaobanDepartment::getDepartmentId).collect(Collectors.toList());
            list.addAll(departmentIds);
        }
        return list;
    }
}
