package ink.wgink.login.oauth2.client.service.department.impl;

import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.login.oauth2.client.remote.department.IDepartmentRemoteService;
import ink.wgink.login.oauth2.client.service.department.IDepartmentService;
import ink.wgink.module.oauth2.manager.OAuth2ClientTokenManager;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.dtos.ZTreeDTO;
import ink.wgink.pojo.dtos.department.DepartmentDTO;
import ink.wgink.pojo.dtos.department.DepartmentSimpleDTO;
import ink.wgink.pojo.pos.DepartmentPO;
import ink.wgink.pojo.result.SuccessResultData;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.pojo.vos.IdsVO;
import ink.wgink.properties.ApiPathProperties;
import ink.wgink.util.string.WStringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @ClassName: DepartmentServiceImpl
 * @Description: 组织部门
 * @Author: wanggeng
 * @Date: 2021/9/22 10:33 下午
 * @Version: 1.0
 */
@Service
public class DepartmentServiceImpl extends DefaultBaseService implements IDepartmentService {

    @Autowired
    private IDepartmentRemoteService departmentRemoteService;
    @Autowired
    private ApiPathProperties apiPathProperties;

    @Override
    public List<DepartmentDTO> list(Map<String, Object> params) {
        return departmentRemoteService.list(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), params);
    }

    @Override
    public List<DepartmentDTO> listByIds(List<String> ids) {
        if(ids.isEmpty()) {
            return new ArrayList<>();
        }
        IdsVO idsVO = new IdsVO();
        idsVO.setIds(ids);
        return departmentRemoteService.listByIds(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), idsVO);
    }

    @Override
    public List<DepartmentDTO> listByParentId(String departmentParentId) {
        Map<String, Object> params = getHashMap(2);
        params.put("departmentParentId", departmentParentId);
        return list(params);
    }

    @Override
    public List<DepartmentDTO> listByAreaCode(String departmentAreaCode) {
        Map<String, Object> params = getHashMap(2);
        params.put("departmentAreaCode", departmentAreaCode);
        return list(params);
    }

    @Override
    public List<DepartmentDTO> listByAreaCodeAndOrder(String departmentAreaCode, String order) {
        Map<String, Object> params = getHashMap(6);
        params.put("departmentAreaCode", departmentAreaCode);
        params.put("sort", "departmentAreaCode");
        params.put("order", order);
        return list(params);
    }

    @Override
    public List<DepartmentDTO> listAllByAreaCode(String departmentAreaCode) {
        Map<String, Object> params = getHashMap(2);
        params.put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(departmentAreaCode, '0', 3));
        return list(params);
    }

    @Override
    public List<DepartmentDTO> listAllByAreaCodeAndOrder(String departmentAreaCode, String order) {
        Map<String, Object> params = getHashMap(6);
        params.put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(departmentAreaCode, '0', 3));
        params.put("sort", "departmentAreaCode");
        params.put("order", order);
        return list(params);
    }

    @Override
    public List<DepartmentDTO> listSubAllByAreaCode(String departmentAreaCode) {
        Map<String, Object> params = getHashMap(4);
        params.put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(departmentAreaCode, '0', 3));
        params.put("excludeDepartmentAreaCode", departmentAreaCode);
        return list(params);
    }

    @Override
    public List<DepartmentDTO> listSubAllByAreaCodeAndOrder(String departmentAreaCode, String order) {
        Map<String, Object> params = getHashMap(8);
        params.put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(departmentAreaCode, '0', 3));
        params.put("excludeDepartmentAreaCode", departmentAreaCode);
        params.put("sort", "departmentAreaCode");
        params.put("order", order);
        return list(params);
    }

    @Override
    public DepartmentDTO get(String departmentId) {
        return departmentRemoteService.get(apiPathProperties.getUserCenter(), departmentId, OAuth2ClientTokenManager.getInstance().getToken().getAccessToken());
    }

    @Override
    public SuccessResultList<List<DepartmentDTO>> listPage(ListPage page) {
        return departmentRemoteService.listPage(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), page.getPage(), page.getRows(), page.getParams());
    }

    @Override
    public SuccessResultList<List<DepartmentDTO>> listPageByParentId(String departmentParentId, ListPage page) {
        page.getParams().put("departmentParentId", departmentParentId);
        return listPage(page);
    }

    @Override
    public SuccessResultList<List<DepartmentDTO>> listPageByAreaCode(String areaCode, ListPage page) {
        page.getParams().put("departmentAreaCode", areaCode);
        return listPage(page);
    }

    @Override
    public SuccessResultList<List<DepartmentDTO>> listPageAllByAreaCode(String departmentAreaCode, ListPage page) {
        page.getParams().put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(departmentAreaCode, '0', 3));
        return listPage(page);
    }

    @Override
    public SuccessResultList<List<DepartmentDTO>> listPageSubAllByAreaCode(String departmentAreaCode, ListPage page) {
        page.getParams().put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(departmentAreaCode, '0', 3));
        page.getParams().put("excludeDepartmentAreaCode", departmentAreaCode);
        return listPage(page);
    }

    @Override
    public SuccessResultList<List<DepartmentDTO>> listPageSubAllByAreaCodeAndType(String departmentAreaCode, Integer departmentType, ListPage page) {
        page.getParams().put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(departmentAreaCode, '0', 3));
        page.getParams().put("excludeDepartmentAreaCode", departmentAreaCode);
        page.getParams().put("departmentType", departmentType);
        return listPage(page);
    }

    @Override
    public List<DepartmentDTO> listAll(Map<String, Object> params) {
        return departmentRemoteService.listAll(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), params);
    }

    @Override
    public List<ZTreeDTO> listZTree(Map<String, Object> params) {
        return departmentRemoteService.listZtree(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), params);
    }

    @Override
    public List<ZTreeDTO> listZTree(String departmentParentId, Map<String, Object> params) {
        params.put("id", departmentParentId);
        return listZTree(params);
    }

    @Override
    public List<ZTreeDTO> listZTree(String departmentParentId, Integer departmentType) {
        Map<String, Object> params = getHashMap(4);
        params.put("id", departmentParentId);
        params.put("departmentType", departmentType);
        return listZTree(params);
    }

    @Override
    public List<ZTreeDTO> listZTreeByAreaCodeAndParentId(String departmentAreaCode, String departmentParentId) {
        Map<String, Object> params = getHashMap(4);
        params.put("departmentAreaCode", departmentAreaCode);
        params.put("id", departmentParentId);
        return listZTree(params);
    }

    @Override
    public List<ZTreeDTO> listZTreeByAreaCodeAndParentIdAndType(String departmentAreaCode, String departmentParentId, Integer departmentType) {
        if (StringUtils.isBlank(departmentAreaCode)) {
            return new ArrayList<>();
        }
        if (StringUtils.isBlank(departmentParentId)) {
            return new ArrayList<>();
        }
        if (departmentType == null) {
            return new ArrayList<>();
        }
        return departmentRemoteService.listZTreeByAreaCodeAndParentIdAndType(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), departmentAreaCode, departmentParentId, departmentType);
    }

    @Override
    public List<String> listId(Map<String, Object> params) {
        return departmentRemoteService.listId(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), params);
    }

    @Override
    public List<String> listRootId(List<DepartmentSimpleDTO> departmentSimpleDTOs) {
        List<String> departmentIds = new ArrayList<>();
        if (Objects.isNull(departmentSimpleDTOs) || departmentSimpleDTOs.isEmpty()) {
            return departmentIds;
        }
        List<DepartmentSimpleDTO> departmentList = new ArrayList<>(departmentSimpleDTOs);
        List<DepartmentSimpleDTO> departmentTempList = new ArrayList<>(departmentSimpleDTOs);
        for (int i = 0; i < departmentList.size(); i++) {
            DepartmentSimpleDTO departmentSimpleDTO = null;
            // 找出CODE
            for (DepartmentSimpleDTO department : departmentList) {
                DepartmentSimpleDTO higherDepartmentSimpleDTO = getHigherLevel(departmentList.get(i), department);
                if (higherDepartmentSimpleDTO != null) {
                    departmentSimpleDTO = higherDepartmentSimpleDTO;
                }
            }
            departmentIds.add(departmentSimpleDTO.getDepartmentId());
            // 删除包含关系的内容
            for (int j = 0; j < departmentList.size(); j++) {
                if (StringUtils.startsWith(departmentList.get(j).getDepartmentCode(), departmentSimpleDTO.getDepartmentCode())) {
                    departmentList.remove(j);
                    j--;
                }
            }
            for (int j = 0; j < departmentTempList.size(); j++) {
                if (StringUtils.startsWith(departmentTempList.get(j).getDepartmentCode(), departmentSimpleDTO.getDepartmentCode())) {
                    departmentTempList.remove(j);
                    j--;
                }
            }
            i = -1;
        }
        return departmentIds;
    }

    @Override
    public DepartmentSimpleDTO getHigherLevel(DepartmentSimpleDTO departmentSimpleDTO1, DepartmentSimpleDTO departmentSimpleDTO2) {
        if (StringUtils.startsWith(departmentSimpleDTO1.getDepartmentCode(), departmentSimpleDTO2.getDepartmentCode())) {
            return departmentSimpleDTO2;
        } else if (StringUtils.startsWith(departmentSimpleDTO2.getDepartmentCode(), departmentSimpleDTO1.getDepartmentCode())) {
            return departmentSimpleDTO1;
        }
        return null;
    }

    @Override
    public Integer count(Map<String, Object> params) {
        SuccessResultData<Integer> successResultData = departmentRemoteService.count(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), params);
        return successResultData.getData();
    }

    @Override
    public DepartmentPO getPO(String departmentId) {
        return departmentRemoteService.getPO(apiPathProperties.getUserCenter(), departmentId, OAuth2ClientTokenManager.getInstance().getToken().getAccessToken());
    }

    @Override
    public List<DepartmentPO> listPO(Map<String, Object> params) {
        return departmentRemoteService.listPO(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), params);
    }

    @Override
    public List<DepartmentPO> listPO(List<String> departmentIds) {
        IdsVO idsVO = new IdsVO();
        idsVO.setIds(departmentIds);
        return departmentRemoteService.listPOByIds(apiPathProperties.getUserCenter(), OAuth2ClientTokenManager.getInstance().getToken().getAccessToken(), idsVO);
    }

    @Override
    public List<DepartmentPO> listPOByParentId(String departmentParentId) {
        return departmentRemoteService.listPOByParentId(apiPathProperties.getUserCenter(), departmentParentId, OAuth2ClientTokenManager.getInstance().getToken().getAccessToken());
    }

    @Override
    public List<DepartmentPO> listPOByParentIdAndAddDate(String departmentParentId, String addDate) {
        return departmentRemoteService.listPOByParentIdAndAddDate(apiPathProperties.getUserCenter(), departmentParentId, addDate, OAuth2ClientTokenManager.getInstance().getToken().getAccessToken());
    }

    @Override
    public List<DepartmentPO> listPOByParentIdAndUpdateDate(String departmentParentId, String updateDate) {
        return departmentRemoteService.listPOByParentIdAndUpdateDate(apiPathProperties.getUserCenter(), departmentParentId, updateDate, OAuth2ClientTokenManager.getInstance().getToken().getAccessToken());
    }

    @Override
    public List<DepartmentPO> listPOByAreaCode(String departmentAreaCode) {
        return departmentRemoteService.listPOByAreaCode(apiPathProperties.getUserCenter(), departmentAreaCode, OAuth2ClientTokenManager.getInstance().getToken().getAccessToken());
    }

    @Override
    public List<DepartmentPO> listPOByAreaCodeAndType(String departmentAreaCode, Integer departmentType) {
        return departmentRemoteService.listPOByAreaCodeAndType(apiPathProperties.getUserCenter(), departmentAreaCode, departmentType, OAuth2ClientTokenManager.getInstance().getToken().getAccessToken());
    }

    @Override
    public Integer countByAreaCode(String areaCode) {
        Map<String, Object> params = getHashMap(2);
        params.put("departmentAreaCode", areaCode);
        return count(params);
    }

    @Override
    public Integer countAllByAreaCode(String areaCode) {
        Map<String, Object> params = getHashMap(2);
        params.put("departmentAreaCodeLike", WStringUtil.cutContinuityRepeatCharDesc(areaCode, '0', 3));
        return count(params);
    }
}
