package com.engine.salary.service.impl;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.hrm.service.RolesMembersService;
import com.engine.hrm.service.impl.RolesMembersServiceImpl;
import com.engine.salary.biz.SalarySendRangeObjBiz;
import com.engine.salary.entity.salaryBill.bo.SalarySendRangeBO;
import com.engine.salary.entity.salaryBill.dto.SalarySendInfoListDTO;
import com.engine.salary.entity.salaryBill.dto.SalarySendUserInfoDTO;
import com.engine.salary.entity.salaryBill.po.SalarySendRangeObj;
import com.engine.salary.enums.salarysend.SalarySendRangeTargetTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.SalarySendRangeObjService;
import com.engine.salary.service.SalarySendService;
import com.engine.salary.service.SalarySobService;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.engine.salary.constant.SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY;

public class SalarySendRangeObjServiceImpl extends Service implements SalarySendRangeObjService {

    private SalarySendService getSalarySendService() {
        return ServiceUtil.getService(SalarySendServiceImpl.class, user);
    }

    private RolesMembersService getRolesMembersService() {
        return ServiceUtil.getService(RolesMembersServiceImpl.class, user);
    }

    private SalarySobService getSalarySobService() {
        return ServiceUtil.getService(SalarySobServiceImpl.class, user);
    }

    private final SalarySendRangeObjBiz salarySendRangeObjBiz = new SalarySendRangeObjBiz();

    @Override
    public List<SalarySendRangeObj> listBySalarySendIdAndRangeIds(Long salarySendId, List<Long> rangeIds) {
        if (salarySendId == null || CollectionUtils.isEmpty(rangeIds)) {
            return Collections.emptyList();
        }
        return salarySendRangeObjBiz.applyMapper(mapper ->
                mapper.listBySalarySendIdAndRangeIds(salarySendId, rangeIds, DEFAULT_TENANT_KEY)
        );
    }

    @Override
    public void deleteBySalarySendIds(Collection<Long> salarySendIds) {
        salarySendRangeObjBiz.runMapper(mapper -> mapper.deleteBySalarySendIds(salarySendIds));
    }

    @Override
    public void replaceAllByRangeIds(Long rangeIds, List<SalarySendRangeObj> rangeObjs) {
        for (SalarySendRangeObj rangeObj : rangeObjs) {
            SalarySendRangeTargetTypeEnum targetEnum = SalarySendRangeTargetTypeEnum.fromValue(rangeObj.getTargetType());
            if (targetEnum == null) {
                throw new SalaryRunTimeException("传入范围类型非法");
            }
            if (rangeObj.getTargetType().equals(SalarySendRangeTargetTypeEnum.ALL.getValue())) {
                rangeObj.setTargetId(0L);
            }
        }
        salarySendRangeObjBiz.replaceAllByRangeId(rangeIds, rangeObjs);
    }

    @Override
    public List<Long> getSendInfoIdsBySalarySendIdAndRangeIds(Long salarySendId, List<Long> rangeIds) {
        // 获取范围
        List<SalarySendRangeObj> rangeList =
                salarySendRangeObjBiz.applyMapper(mapper -> mapper.listBySalarySendIdAndRangeIds(salarySendId, rangeIds, DEFAULT_TENANT_KEY));

        // 初始化范围操作类
        SalarySendRangeBO rangeBO = new SalarySendRangeBO();
        for (SalarySendRangeObj rangeObj : rangeList) {
            rangeBO.putNew(rangeObj);
        }
        // 获取当前发放单人员详情
        List<SalarySendInfoListDTO> sendInfoList = getSalarySendService().salarySendInfoList(salarySendId);
        // 获取全部人员id
        List<Long> employeeIds = sendInfoList.stream().map(SalarySendInfoListDTO::getEmployeeId)
                .distinct().collect(Collectors.toList());
        // 查找人员的多维度关联id
        List<SalarySendUserInfoDTO> userInfos =
                salarySendRangeObjBiz.getSalarySendUserInfoDTOs(employeeIds);
        // 筛选在范围中的人员id
        Set<Long> empIds = userInfos.stream()
                .filter(rangeBO::judgeInRange)
                .map(SalarySendUserInfoDTO::getResourceId)
                .distinct().collect(Collectors.toSet());
        // 返回发放详情的id
        return sendInfoList.stream().filter(s -> empIds.contains(s.getEmployeeId()))
                .map(SalarySendInfoListDTO::getId)
                .collect(Collectors.toList());
    }

    @Override
    public void deleteBySalarySendRangeIds(List<Long> salarySendRangeIds) {
        salarySendRangeObjBiz.runMapper(mapper -> mapper.deleteByRangeIds(salarySendRangeIds, DEFAULT_TENANT_KEY));
    }
}
