package com.engine.salary.report.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.common.BaseQueryParam;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.enums.sicategory.DeleteTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.report.SalaryStatisticsPushMapper;
import com.engine.salary.report.entity.dto.SalaryStatisticsPushDetail;
import com.engine.salary.report.entity.dto.SalaryStatisticsPushDetailFormDTO;
import com.engine.salary.report.entity.dto.SalaryStatisticsPushDetailTableDTO;
import com.engine.salary.report.entity.dto.SalaryStatisticsPushTableDTO;
import com.engine.salary.report.entity.param.SalaryStatisticsPushDetailParam;
import com.engine.salary.report.entity.param.SalaryStatisticsPushParam;
import com.engine.salary.report.entity.po.SalaryStatisticsPushDetailPO;
import com.engine.salary.report.entity.po.SalaryStatisticsPushPO;
import com.engine.salary.report.entity.po.SalaryStatisticsReportPO;
import com.engine.salary.report.service.SalaryStatisticsPushDetailService;
import com.engine.salary.report.service.SalaryStatisticsPushService;
import com.engine.salary.report.service.SalaryStatisticsReportService;
import com.engine.salary.report.util.ReportTimeUtil;
import com.engine.salary.service.SalaryEmployeeService;
import com.engine.salary.service.TaxAgentService;
import com.engine.salary.service.impl.SalaryEmployeeServiceImpl;
import com.engine.salary.service.impl.TaxAgentServiceImpl;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import weaver.hrm.User;

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

/**
 * @author Harryxzy
 * @ClassName SalaryStatisticsPushServiceImpl
 * @date 2023/09/11 10:15
 * @description 薪酬统计报表消息推送
 */
public class SalaryStatisticsPushServiceImpl extends Service implements SalaryStatisticsPushService {

    private SalaryStatisticsPushMapper getSalaryStatisticsPushMapper() {
        return MapperProxyFactory.getProxy(SalaryStatisticsPushMapper.class);
    }

    private SalaryStatisticsPushDetailService getSalaryStatisticsPushDetailService(User user) {
        return ServiceUtil.getService(SalaryStatisticsPushDetailServiceImpl.class, user);
    }

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    private SalaryStatisticsReportService getSalaryStatisticsReportService(User user) {
        return ServiceUtil.getService(SalaryStatisticsReportServiceImpl.class, user);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return (TaxAgentService) ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    @Override
    public Map<String, Object> getPushForm() {
        Map<String, Object> resultMap = new HashMap<>();
        // items
        // 分享报表item
        List<Map<String, Object>> reportOptions = buildReportIdsOptions(Long.valueOf(user.getUID()));
        resultMap.put("reportOptions", reportOptions);
        // data
        resultMap.putAll(formData(Long.valueOf(user.getUID())));
        return resultMap;
    }


    private Map<String, Object> formData(Long employeeId) {
        Map<String, Object> data = new HashMap<>();
        SalaryStatisticsPushPO pushPO = getListByEmployeeId(employeeId);
        data.put("pushTitle", pushPO.getPushTitle());
        data.put("mark", pushPO.getMark());
        if (pushPO.getRemind() == null) {
            data.put("remind", "1");
        } else {
            data.put("remind", pushPO.getRemind().toString());
        }
        return data;
    }

    private SalaryStatisticsPushPO getListByEmployeeId(Long uid) {
        List<SalaryStatisticsPushPO> list = getSalaryStatisticsPushMapper().listLatestRecordByCreator(uid);
        if (CollectionUtils.isEmpty(list)) {
            return SalaryStatisticsPushPO.builder().build();
        }
        return list.get(0);
    }


    private List<Map<String, Object>> buildReportIdsOptions(Long employeeId) {
        List<Map<String, Object>> reportIdsOptions = new ArrayList<>();
        List<SalaryStatisticsReportPO> reportPOS = getSalaryStatisticsReportService(user).listAll();
        Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
        if (needAuth) {
            // 只能够分享创建人是本人的报表
            reportPOS = reportPOS.stream().filter(po -> po.getCreator().compareTo(employeeId) == 0).collect(Collectors.toList());
        }
        reportPOS.forEach( po -> {
            Map<String, Object> option = new HashMap<>();
            option.put("id", po.getId().toString());
            option.put("reportName", po.getReportName());
            reportIdsOptions.add(option);
        });

        return reportIdsOptions;
    }

    @Override
    public SalaryStatisticsPushDetail getPushDetail(SalaryStatisticsPushDetailParam param) {
        SalaryStatisticsPushPO salaryStatisticsPushPO = getSalaryStatisticsPushMapper().getById(param.getId());
        if (Objects.isNull(salaryStatisticsPushPO)) {
            throw new SalaryRunTimeException("该分享记录不存在");
        }
        Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
        if (needAuth && salaryStatisticsPushPO.getCreator().compareTo(Long.valueOf(user.getUID())) != 0) {
            throw new SalaryRunTimeException("无权查看该分享记录");
        }
        SalaryStatisticsPushDetail result = new SalaryStatisticsPushDetail();
        result.setDetailForm(buildDetailForm(salaryStatisticsPushPO));
        result.setDetailTable(buildDetailTable(param));
        return result;
    }

    @Override
    public void push(SalaryStatisticsPushParam param) {
        // 生成分享链接中的id参数
        param.setId(createAndGetBatchId(param));
        sendMsg(param);
    }

//    public void configSave(SalaryStatisticsPushParam param, String tenantkey, Long employeeId) {
//        if (StringUtils.isNotEmpty(param.getConfig())) {
//            CreateRuleEntity createRule = new CreateRuleEntity()
//                    .setName(SalaryI18nUtil.getI18nLabel(tenantkey, employeeId, 220428, "分享报表"))
//                    .setUser(new UserEntity(employeeId, tenantkey))
//                    .setModule(MessageModule.HRSA)
//                    .setEvent(MessageEvent.REPORT_SHARING)
//                    .setBusinessId(param.getBusinessId().toString())
//                    .setConfig(param.getConfig());
//            log.info("RuleRest.createRuleV2 -> config ====== {}", param.getConfig());
//            WeaResult<Long> weaResult = ruleRest.createRuleV2(createRule);
//            SalaryAssert.isTrue(weaResult.isStatus(), SalaryI18nUtil.getI18nLabel(184008, "RPC接口创建规则失败"));
//        }
//    }

    @Override
    public void addSharedPush(SalaryStatisticsPushParam param) {
        SalaryStatisticsPushPO pushPO = getSalaryStatisticsPushMapper().getById(param.getId());
        Collection<Long> sharedBy = sharedByValid(param.getSharedBy(), param.getId());
        if (CollectionUtils.isEmpty(sharedBy)) {
            return;
        }
        SalaryStatisticsPushParam pushParam = new SalaryStatisticsPushParam();
        pushParam.setReportIds(Arrays.asList(pushPO.getReportIds().split(",")));
        pushParam.setPushTitle(pushPO.getPushTitle());
//        pushParam.setEmailAccountId(pushPO.getEmailAccountId());
//        pushParam.setEmailAdress(pushParam.getEmailAdress());
        pushParam.setSharedBy((List<Long>) sharedBy);
        pushParam.setStartTime(pushPO.getStartTime());
        pushParam.setEndTime(pushPO.getEndTime());
//        pushParam.setPushChannel(Arrays.stream(pushPO.getPushChannel().split(",")).map(Integer::valueOf).collect(Collectors.toList()));
        pushParam.setMark(pushPO.getMark());
        pushParam.setId(pushPO.getId());
        sendMsg(pushParam);
    }

    public Collection<Long> sharedByValid(List<Long> sharedBy, Long batchId) {
        List<SalaryStatisticsPushDetailPO> list = getSalaryStatisticsPushDetailService(user).queryPushDetailPOByBatchIdAndEmpIds(batchId, sharedBy);
        List<SalaryStatisticsPushDetailPO> finalList = list;
        // 获取需要分享或重新分享的人
        sharedBy = sharedBy.stream().filter(shareId -> {
            List<SalaryStatisticsPushDetailPO> collect = finalList.stream().filter(po -> Objects.equals(po.getEmployeeId(), shareId)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(collect)) {
                return true;
            }
            boolean enabledSend = collect.stream().anyMatch(po -> Objects.equals(po.getPushStatus(), "true") && !Objects.equals(po.getRebackStatus(), "true"));
            return !enabledSend;

        }).collect(Collectors.toList());
        return sharedBy;
    }

    public void sendMsg(SalaryStatisticsPushParam param) {
        // 获取被分享人
        List<DataCollectionEmployee> receivers = getSalaryEmployeeService(user).getEmployeeByIds(param.getSharedBy());
        // 发送消息
        receivers.forEach(receiver -> {
            // 发送消息...
            // 发送成功
            doSuccess(receiver, param);
        });
    }


//    @Override
//    public void rePush(Long id, Long employeeId, String tenantKey) {
//        SalaryStatisticsPushDetailPO detailPO = salaryStatisticsPushDetailMapper.selectById(id);
//        SalaryStatisticsPushPO pushPO = salaryStatisticsPushMapper.selectById(detailPO.getBatchId());
//        SalaryStatisticsPushParam param = new SalaryStatisticsPushParam();
//        param.setReportIds(Arrays.asList(pushPO.getReportIds().split(",")));
//        param.setPushTitle(pushPO.getPushTitle());
//        param.setEmailAdress(pushPO.getEmailAccount());
//        param.setEmailAccountId(pushPO.getEmailAccountId());
//        param.setSharedBy(Collections.singletonList(detailPO.getEmployeeId()));
//        param.setStartTime(pushPO.getStartTime());
//        param.setEndTime(pushPO.getEndTime());
//        param.setPushChannel(Arrays.stream(pushPO.getPushChannel().split(",")).map(Integer::valueOf).collect(Collectors.toList()));
//        param.setMark(pushPO.getMark());
//        param.setId(pushPO.getId());
//        sendMsg(param, employeeId, tenantKey);
//    }

    @Override
    public void cancel(Long id) {
        SalaryStatisticsPushDetailPO detailPO = getSalaryStatisticsPushDetailService(user).getById(id);
        if (ObjectUtil.isEmpty(detailPO)) {
            throw new SalaryRunTimeException("该明细不存在");
        }
        cancelSingle(detailPO);
    }

    public void cancelSingle(SalaryStatisticsPushDetailPO detailPO) {
        // 撤回消息...
        // 撤回分享记录
        doCancelResult(detailPO);
    }

    @Override
    public void cancelAll(Long id) {
        // 根据分享批次id，获取所有的分享明细
        List<SalaryStatisticsPushDetailPO> salaryStatisticsPushDetailPOS = getSalaryStatisticsPushDetailService(user).queryPushDetailPOByBatchIds(Collections.singletonList(id));
        salaryStatisticsPushDetailPOS.forEach(po -> cancelSingle(po));
    }

//    public List<SalaryStatisticsPushDetailPO> getSalatyPushDetailPOSBybatchId(Long batchId, String tenantKey) {
//        return new LambdaQueryChainWrapper<>(salaryStatisticsPushDetailMapper)
//                .eq(SalaryStatisticsPushDetailPO::getTenantKey, tenantKey)
//                .eq(SalaryStatisticsPushDetailPO::getBatchId, batchId)
//                .eq(SalaryStatisticsPushDetailPO::getDeleteType, DeleteTypeEnum.NOT_DELETED.getValue())
//                .isNull(SalaryStatisticsPushDetailPO::getRebackStatus)
//                .list();
//    }
//
//    @Override
//    public SalaryStatisticsPushPO getById(Long id, String tenantKey) {
//        return salaryStatisticsPushMapper.selectById(id);
//    }
//
//    @Override
//    public List<SalaryStatisticsPushDetailPO> getPushDetailsById(Long batchId, String tenantKey) {
//        return new LambdaQueryChainWrapper<>(salaryStatisticsPushDetailMapper)
//                .eq(SalaryStatisticsPushDetailPO::getTenantKey, tenantKey)
//                .eq(SalaryStatisticsPushDetailPO::getDeleteType, DeleteTypeEnum.NOT_DELETED.getValue())
//                .eq(SalaryStatisticsPushDetailPO::getBatchId, batchId)
//                .list();
//    }


    @Override
    public void updateReportViewStatus(List<Long> batchId, Long uid) {
        List<SalaryStatisticsPushDetailPO> salaryStatisticsPushDetailPOS = getSalaryStatisticsPushDetailService(user).queryPushDetailPOByBatchIds(batchId);
        salaryStatisticsPushDetailPOS.stream().filter(po -> Objects.equals(po.getPushStatus(), "true") && !(Objects.equals(po.getRebackStatus(), "true")) && Objects.equals(uid, po.getEmployeeId()))
                .collect(Collectors.toList()).forEach(e -> {
            e.setViewStatus("true");
            e.setUpdateTime(new Date());
            getSalaryStatisticsPushDetailService(user).updateIgnoreNull(e);
        });
    }

//    @Override
//    public void sendViewedMsg(Long batchId, Long reportId, Long employeeId, String tenantKey) {
//        SalaryStatisticsPushPO pushPO = salaryStatisticsPushMapper.selectById(batchId);
//        if (!Objects.equals(1, pushPO.getRemind())) {
//            return;
//        }
//        List<SalaryStatisticsPushDetailPO> salaryStatisticsPushDetailPOS = queryPushDetailPOByBatchId(batchId, tenantKey);
//        List<SalaryStatisticsPushDetailPO> detailPOList = salaryStatisticsPushDetailPOS.stream().filter(po -> Objects.equals(po.getPushStatus(), "true") && po.getRebackStatus() == null && Objects.equals(employeeId, po.getEmployeeId())).collect(Collectors.toList());
//        if (CollectionUtils.isEmpty(detailPOList)) {
//            return;
//        }
//        SalaryStatisticsPushParam param = new SalaryStatisticsPushParam();
//        param.setPushTitle(SalaryI18nUtil.getI18nLabel(tenantKey, employeeId, 227925, "报表已查看提醒"));
//        param.setSharedBy(Collections.singletonList(pushPO.getCreator()));
//        param.setPushChannel(Collections.singletonList(MessageChannelEnum.IM.getType()));
//        param.setMark(buildViewMark(pushPO, detailPOList, employeeId, tenantKey));
//        SendMessageEntity entity = buildSendMessage(param, employeeId, tenantKey);
//        entity.getEntity().setPcUrl("");
//        entity.getEntity().setH5Url("");
//        entity.getEntity().setPcLinkeType(0);
//        entity.getEntity().setH5LinkeType(0);
//        List<UserEntity> receivers = buildReceivers(param, tenantKey);
//        // 发送消息
//        receivers.forEach(receiver -> {
//            entity.setReceivers(Collections.singletonList(receiver));
//            try {
//                asyncSystemMessageRest.sendMsg(entity);
//            } catch (Exception e) {
//                log.error("查看消息发送失败", e);
//            }
//        });
//    }
//
//    public String buildViewMark(SalaryStatisticsPushPO pushPO, List<SalaryStatisticsPushDetailPO> detailPOList, Long employeeId, String tenantkey) {
//        SimpleEmployee employee = hrmCommonEmployeeService.getById(employeeId);
//        if (employee == null) {
//            return SalaryI18nUtil.getI18nLabel(tenantkey, employeeId, 227926, "消息创建人已不存在");
//        }
//        return employee.getUsername() +
//                SalaryI18nUtil.getI18nLabel(tenantkey, employeeId, 227927, "已查看您分享的报表。") +
//                SalaryI18nUtil.getI18nLabel(tenantkey, employeeId, 227928, "分享主题：") +
//                pushPO.getPushTitle() + "，" +
//                SalaryI18nUtil.getI18nLabel(tenantkey, employeeId, 233590, "分享时间：") +
//                detailPOList.get(0).getPushTime() +
//                "。";
//    }
//

    public void doCancelResult(SalaryStatisticsPushDetailPO detailPO) {
        // 判断撤回消息是否成功...
        // 消息撤回成功的话撤回分享记录
        detailPO.setRebackStatus("true");
        detailPO.setRebackTime(ReportTimeUtil.getFormatLocalDateTime(LocalDateTime.now()));
        getSalaryStatisticsPushDetailService(user).updateIgnoreNull(detailPO);
    }



//    public CancleMessageEntity buildCancelMessageEntity(SalaryStatisticsPushDetailPO po, Long employeeId, String tenantKey) {
//        SalaryStatisticsPushPO pushPO = salaryStatisticsPushMapper.selectById(po.getBatchId());
//        CancleMessageEntity cancleMessageEntity = new CancleMessageEntity();
//        cancleMessageEntity.setMsgId(po.getMsgId());
//        cancleMessageEntity.setModule(MessageModule.HRSA);
//        cancleMessageEntity.setEvent(MessageEvent.REPORT_SHARING);
//        cancleMessageEntity.setText(SalaryI18nUtil.getI18nLabel(tenantKey, employeeId, 221630, "此消息已收回,如有问题,请联系管理员"));
//        Entity entity = new Entity();
//        entity.setId(String.valueOf(IdGenerator.generate()));
//        entity.setModule(EntityType.hrmsalary.name());
//        entity.setName(pushPO.getPushTitle());
//        cancleMessageEntity.setEntity(entity);
//        UserEntity user = new UserEntity(employeeId, tenantKey);
//        SimpleEmployee employeeById = hrmCommonEmployeeService.getEmployeeById(employeeId, tenantKey);
//        user.setName(employeeById.getUsername());
//        cancleMessageEntity.setOperator(user);
//        return cancleMessageEntity;
//    }

    public void doSuccess(DataCollectionEmployee receiver, SalaryStatisticsPushParam param) {
        List<SalaryStatisticsPushDetailPO> pushDetailByBatchIdAndEmpId = getSalaryStatisticsPushDetailService(user).listSome(SalaryStatisticsPushDetailPO.builder()
                .batchId(param.getId())
                .employeeId(receiver.getEmployeeId())
                .build());
        Date now = new Date();
        if (CollectionUtils.isEmpty(pushDetailByBatchIdAndEmpId)) {
            SalaryStatisticsPushDetailPO detailPO = SalaryStatisticsPushDetailPO.builder()
                    .id(IdGenerator.generate())
                    .batchId(param.getId())
//                    .msgId(result.getData())
                    .pushStatus("true")
                    .pushTime(ReportTimeUtil.getFormatLocalDateTime(LocalDateTime.now()))
                    .deleteType(DeleteTypeEnum.NOT_DELETED.getValue())
                    .employeeId(receiver.getEmployeeId())
                    .updateTime(now)
                    .creator(Long.valueOf(user.getUID()))
                    .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                    .build();
            getSalaryStatisticsPushDetailService(user).insertIgnoreNull(detailPO);
        } else {
            SalaryStatisticsPushDetailPO PO = pushDetailByBatchIdAndEmpId.get(0);
            PO.setPushStatus("true");
            PO.setRebackStatus("");
            PO.setRebackTime("");
            PO.setViewStatus("false");
//            PO.setMsgId(result.getData());
            PO.setPushTime(ReportTimeUtil.getFormatLocalDateTime(LocalDateTime.now()));
            PO.setUpdateTime(now);
            PO.setCreator(Long.valueOf(user.getUID()));
            getSalaryStatisticsPushDetailService(user).updateIgnoreNull(PO);
        }
    }

//    public void delBatchId(Long id) {
//        SalaryStatisticsPushPO pushPO = salaryStatisticsPushMapper.selectById(id);
//        pushPO.setDeleteType(DeleteTypeEnum.PHYSICAL_DELETED.getValue());
//        salaryStatisticsPushMapper.updateById(pushPO);
//    }
//
//    public void paramValid(SalaryStatisticsPushParam param, Long employeeId, String tenantKey) {
//        channelCheck(param, employeeId, tenantKey);
//        emileCheck(param, employeeId, tenantKey);
//        bridgeCheck(param, employeeId, tenantKey);
//    }

    public Long createAndGetBatchId(SalaryStatisticsPushParam param) {
        Date now = new Date();
        SalaryStatisticsPushPO pushPO = SalaryStatisticsPushPO.builder()
                .id(IdGenerator.generate())
                .creator(Long.valueOf(user.getUID()))
                .deleteType(DeleteTypeEnum.NOT_DELETED.getValue())
                .createTime(now)
                .updateTime(now)
                .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
//                .pushChannel(buildChannelString(param))
                .startTime(param.getStartTime())
                .endTime(param.getEndTime())
                .remind(param.getRemind())
//                .emailAccount(param.getEmailAdress())
//                .emailAccountId(param.getEmailAccountId())
                .mark(param.getMark())
//                .pushTitle(param.getPushTitle())
                .reportIds(String.join(",", param.getReportIds()))
                .build();
        getSalaryStatisticsPushMapper().insertIgnoreNull(pushPO);
        return pushPO.getId();
    }

//    public String buildChannelString(SalaryStatisticsPushParam param) {
//        Set<MessageChannelEnum> channelEnums = buildChannel(param);
//        List<String> channelType = channelEnums.stream().map(e -> String.valueOf(e.getType())).collect(Collectors.toList());
//        return String.join(",", channelType);
//    }
//
//
//    public void channelCheck(SalaryStatisticsPushParam param, Long employeeId, String tenantKey) {
//        if (CollectionUtils.isEmpty(param.getPushChannel())) {
//            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(tenantKey, employeeId, 221582, "至少有一个发送通道"));
//        }
//    }
//
//    public void emileCheck(SalaryStatisticsPushParam param, Long employeeId, String tenantKey) {
//        if (param.getPushChannel().contains(MessageChannelEnum.EMAIL.getType())) {
//            if (!isEnableEmail(tenantKey)) {
//                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(tenantKey, employeeId, 221580, "邮件模块未采购,不可使用邮件通道!"));
//            }
//            // 接收者邮箱校验
//            List<SimpleEmployee> employeeByIds = hrmCommonEmployeeService.getEmployeeByIds(param.getSharedBy(), tenantKey);
//            List<String> usernameList = new ArrayList<>();
//            employeeByIds.forEach(employee -> {
//                if (StringUtils.isEmpty(employee.getEmail())) {
//                    usernameList.add(employee.getUsername());
//                }
//            });
//            if (CollectionUtils.isNotEmpty(usernameList)) {
//                throw new SalaryRunTimeException(String.join(",", usernameList) + SalaryI18nUtil.getI18nLabel(tenantKey, employeeId, 221578, "没有可用邮箱，请先配置再发送!"));
//            }
//            if (StringUtils.isEmpty(param.getEmailAdress())) {
//                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(tenantKey, employeeId, 224278, "发送邮箱不可为空"));
//            }
//        }
//    }
//
//    public void bridgeCheck(SalaryStatisticsPushParam param, Long employeeId, String tenantKey) {
//        if (param.getPushChannel().contains(MessageChannelEnum.CLOUD_BRIDGE.getType()) && !isEnableEbridge(tenantKey)) {
//            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(tenantKey, employeeId, 221581, "云桥模块未采购,不可使用云桥通道!"));
//        }
//    }
//
//    public SendMessageEntity buildSendMessage(SalaryStatisticsPushParam param, Long employeeId, String tenantKey) {
//        // 域名
//        param.setDomain(weaverConfigUtils.getValueFromDataMap("primary.domain"));
//        SendMessageEntity entity = new SendMessageEntity();
//        // 模块
//        entity.setModule(MessageModule.HRSA);
//        // 消息事件
//        entity.setEvent(MessageEvent.REPORT_SHARING);
//        // 消息通道
//        entity.setChannels(buildChannel(param));
//        // 主题
//        entity.setText(param.getPushTitle());
//        // 发送者信息
//        entity.setSender(buildSendEntity(employeeId, tenantKey));
//        // 接收者
//        entity.setReceivers(buildReceivers(param, tenantKey));
//        // emile消息体
//        entity.setEmailInfo(buildEmailEntity(param, employeeId, tenantKey));
//        // im消息体
//        entity.setEntity(buildImEntity(param));
//        // 消息内容  im和bridge公用
//        entity.setText(param.getMark());
//        // 云桥
//        entity.setTitle(param.getPushTitle());
//        return entity;
//    }
//
//    public UserEntity buildSendEntity(Long employeeId, String tenantKey) {
//        SimpleEmployee employeeById = hrmCommonEmployeeService.getEmployeeById(employeeId, tenantKey);
//        UserEntity userEntity = new UserEntity();
//        userEntity.setEmployeeId(employeeId);
//        userEntity.setTenantKey(tenantKey);
//        userEntity.setName(employeeById.getUsername());
//        return userEntity;
//    }
//
//
//    public List<UserEntity> buildReceivers(SalaryStatisticsPushParam param, String tenantKey) {
//        List<SimpleEmployee> simpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(param.getSharedBy(), tenantKey);
//        return simpleEmployeeList.stream().map(employee -> {
//            UserEntity userEntity = new UserEntity();
//            userEntity.setEmployeeId(employee.getEmployeeId());
//            userEntity.setTenantKey(tenantKey);
//            userEntity.setEmail(employee.getEmail());
//            return userEntity;
//        }).collect(Collectors.toList());
//    }
//
//    public Entity buildImEntity(SalaryStatisticsPushParam param) {
//        Entity imEntity = new Entity();
//        imEntity.setId(IDGenerator.generateId());
//        imEntity.setName(param.getPushTitle());
//        imEntity.setModule("hrmsalary");
//        imEntity.setPcLinkeType(2);
//        imEntity.setH5LinkeType(2);
//        imEntity.setPcUrl(buildPcUrl(param));
//        imEntity.setH5Url(buildPcUrl(param));
//        return imEntity;
//    }
//
//    public String buildPcUrl(SalaryStatisticsPushParam param) {
//        return param.getDomain() + String.format("/sp/ebdpage/view/828107636586323968?id=%s&share=true", param.getId());
//    }
//
//    public EmailEntity buildEmailEntity(SalaryStatisticsPushParam param, Long employeeId, String tenantKey) {
//        EmailEntity emailEntity = new EmailEntity();
//        if (param.getEmailAccountId() == null) {
//            return emailEntity;
//        }
//        emailEntity.setEmailSubject(param.getPushTitle());
//        emailEntity.setEmailContent(buildEmailContent(param));
//        emailEntity.setMailUserAccountId(param.getEmailAccountId());
//        return emailEntity;
//    }
//
//    public String buildEmailContent(SalaryStatisticsPushParam param) {
//        String emailContent = "<div>" +
//                "<div style=fontSize: '12px'>" +
//                param.getMark() +
//                "</div>" +
//                "<a href='" + buildPcUrl(param) + "'" + "target='_blank' style=fontSize: '12px', color: 'var(--primary)', cursor: 'pointer', textDecoration: 'none' rel='noreferrer'>" + buildPcUrl(param) + "</a>" +
//                "</div>";
//        return emailContent;
//    }
//
//    public Set<MessageChannelEnum> buildChannel(SalaryStatisticsPushParam param) {
//        Set<MessageChannelEnum> channelEnums = new HashSet<>();
//        if (param.getPushChannel().contains(MessageChannelEnum.EMAIL.getType())) {
//            channelEnums.add(MessageChannelEnum.EMAIL);
//        }
//        if (param.getPushChannel().contains(MessageChannelEnum.CLOUD_BRIDGE.getType())) {
//            channelEnums.add(MessageChannelEnum.CLOUD_BRIDGE);
//        }
//        if (param.getPushChannel().contains(MessageChannelEnum.IM.getType())) {
//            channelEnums.add(MessageChannelEnum.IM);
//        }
//        return channelEnums;
//    }
//
//    public Boolean isEnableEmail(String tenantKey) {
////        boolean isPayModule = remoteTenantService.isPayModule(tenantKey, EntityType.email.name());
////        boolean checkDisplayModule = CollectionUtils.emptyIfNull(baseEnvInfoService.listDisplayModules(tenantKey)).stream().anyMatch(m -> m.equals(EntityType.email.name()));
////        return isPayModule && checkDisplayModule;
//        return CollectionUtils.emptyIfNull(baseEnvInfoService.listDisplayModules(tenantKey)).stream().anyMatch(m -> m.equals(EntityType.email.name()));
//    }
//
//    public Boolean isEnableEbridge(String tenantKey) {
//        return CollectionUtils.emptyIfNull(baseEnvInfoService.listDisplayModules(tenantKey)).stream().anyMatch(m -> m.equals("wechatEnterprise"));
//    }

    public SalaryStatisticsPushDetailFormDTO buildDetailForm(SalaryStatisticsPushPO salaryStatisticsPushPO) {
        List<Long> reportIds = Arrays.stream(salaryStatisticsPushPO.getReportIds().split(",")).map(Long::valueOf).collect(Collectors.toList());
        List<String> reportNames = getSalaryStatisticsReportService(user).getByIds(reportIds).stream().map(SalaryStatisticsReportPO::getReportName).collect(Collectors.toList());
        SalaryStatisticsPushDetailFormDTO formDTO = SalaryStatisticsPushDetailFormDTO.builder()
                .remark(salaryStatisticsPushPO.getMark())
                .effectiveTime(salaryStatisticsPushPO.getStartTime() + "-" + salaryStatisticsPushPO.getEndTime())
                .reportName(String.join("、", reportNames))
                .build();
        return formDTO;
    }

    public PageInfo<SalaryStatisticsPushDetailTableDTO> buildDetailTable(SalaryStatisticsPushDetailParam param) {
        List<SalaryStatisticsPushDetailPO> salaryStatisticsPushDetailPOS = getSalaryStatisticsPushDetailService(user).queryPushDetailPOByBatchIds(Arrays.asList(param.getId()));
        PageInfo<SalaryStatisticsPushDetailTableDTO> dtoPage = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), SalaryStatisticsPushDetailTableDTO.class);
        List<SalaryStatisticsPushDetailTableDTO> records = salaryStatisticsPushDetailPOS.stream().map(po -> {
            return SalaryStatisticsPushDetailTableDTO.builder()
                    .id(po.getId())
                    .pushStatus(buildStatus(po.getPushStatus()))
                    .pushTime(po.getPushTime())
                    .rebackStatus(buildStatus(po.getRebackStatus()))
                    .viewStatus(buildViewStatus(po.getViewStatus()))
                    .rebackTime(po.getRebackTime())
                    .userName(buildUserName(po.getEmployeeId()))
                    .employeeId(po.getEmployeeId())
                    .build();
        }).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(param.getUserNameSearch())) {
            records = records.stream().filter(record -> record.getUserName().contains(param.getUserNameSearch())).collect(Collectors.toList());
        }
        dtoPage.setList(records);
        dtoPage.setTotal(records.size());
        return dtoPage;
    }

    public String buildUserName(Long employeeId) {
        DataCollectionEmployee employeeById = getSalaryEmployeeService(user).getEmployeeById(employeeId);
        if (employeeById != null) {
            return employeeById.getUsername();
        }
        return "";
    }

    public String buildViewStatus(String status) {
        if (Objects.equals(status, "true")) {
            return SalaryI18nUtil.getI18nLabel(0, "已查看");
        } else {
            return SalaryI18nUtil.getI18nLabel(0, "未查看");
        }
    }

    public String buildStatus(String status) {
        if (StringUtils.isEmpty(status)) {
            return "";
        }
        if (Objects.equals("true", status)) {
            return SalaryI18nUtil.getI18nLabel(0, "成功");
        }
        if (Objects.equals("false", status)) {
            return SalaryI18nUtil.getI18nLabel(0, "失败");
        }
        return "";
    }

    @Override
    public PageInfo<SalaryStatisticsPushTableDTO> getPushTable(BaseQueryParam param) {
        Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
        List<SalaryStatisticsPushPO> salaryStatisticsPushPOS;
        if (needAuth) {
            salaryStatisticsPushPOS = getSalaryStatisticsPushMapper().listSome(SalaryStatisticsPushPO.builder().creator(Long.valueOf(user.getUID())).build());
        } else {
            salaryStatisticsPushPOS = getSalaryStatisticsPushMapper().listSome(SalaryStatisticsPushPO.builder().build());
        }

        salaryStatisticsPushPOS = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), salaryStatisticsPushPOS);
        PageInfo<SalaryStatisticsPushTableDTO> dtoPageInfo = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), SalaryStatisticsPushTableDTO.class);
        if (CollectionUtils.isNotEmpty(salaryStatisticsPushPOS)) {
            // 获取报表名称 key:报表id； value：报表名称
            List<Long> reportIds = salaryStatisticsPushPOS.stream().map(po -> Arrays.asList(StringUtils.split(po.getReportIds(), ",")))
                    .flatMap(Collection::stream).distinct().map(Long::valueOf).collect(Collectors.toList());
            Map<Long, String> statisticsNameMap = SalaryEntityUtil.convert2Map(getSalaryStatisticsReportService(user).getByIds(reportIds), SalaryStatisticsReportPO::getId, SalaryStatisticsReportPO::getReportName);

            // 获取报表分享明细 key:批次id； value：分享明细列表
            List<Long> batchIds = salaryStatisticsPushPOS.stream().map(po -> Long.valueOf(po.getId())).collect(Collectors.toList());
            Map<Long, List<SalaryStatisticsPushDetailPO>> groupByBatchId;
            if (CollectionUtils.isNotEmpty(batchIds)) {
                groupByBatchId = SalaryEntityUtil.group2Map(
                        getSalaryStatisticsPushDetailService(user).queryPushDetailPOByBatchIds(batchIds),
                        SalaryStatisticsPushDetailPO::getBatchId);
            } else {
                groupByBatchId = Collections.emptyMap();
            }
            List<SalaryStatisticsPushTableDTO> dtoList = salaryStatisticsPushPOS.stream().map(po -> {
                return SalaryStatisticsPushTableDTO.builder()
                        .reportName(buildReportName(po.getReportIds(), statisticsNameMap))
                        .effectiveTime(StringUtils.isEmpty(po.getStartTime()) ? "" : po.getStartTime()
                                + "——" + (StringUtils.isEmpty(po.getEndTime()) ? "" : po.getEndTime()))
                        .id(po.getId())
                        .successPush(buildSuccessPush(groupByBatchId.get(po.getId())))
                        .sharedView(buildSharedView(groupByBatchId.get(po.getId())))
                        .build();
            }).collect(Collectors.toList());
            dtoPageInfo.setList(dtoList);
            dtoPageInfo.setTotal(dtoList.size());
        }
        return dtoPageInfo;
    }

    public String buildSharedView(List<SalaryStatisticsPushDetailPO> list) {
        List<Long> successEmpIds = list.stream().filter(po -> Objects.equals(po.getPushStatus(), "true") && !(Objects.equals(po.getRebackStatus(), "true"))).map(SalaryStatisticsPushDetailPO::getEmployeeId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(successEmpIds)) {
            return "0/0";
        }
        List<Long> viewEmpIds = list.stream().filter(po -> Objects.equals(po.getViewStatus(), "true")).map(SalaryStatisticsPushDetailPO::getEmployeeId).collect(Collectors.toList());
        return viewEmpIds.size() + "/" + successEmpIds.size();
    }

    public String buildSuccessPush(List<SalaryStatisticsPushDetailPO> list) {
        List<DataCollectionEmployee> employeeByIds = getSalaryEmployeeService(user).getEmployeeByIds(list.stream().filter(po -> Objects.equals(po.getPushStatus(), "true") && !(Objects.equals(po.getRebackStatus(), "true"))).map(SalaryStatisticsPushDetailPO::getEmployeeId).collect(Collectors.toList()));
        Set<String> employeeName = employeeByIds.stream().map(DataCollectionEmployee::getUsername).collect(Collectors.toSet());
        return String.join("、", employeeName);
    }

    public String buildReportName(String reportIds, Map<Long, String> statisticsNameMap) {
        List<String> ids = Arrays.asList(reportIds.split(","));
        List<String> reportName = Lists.newArrayList();
        ids.forEach(id -> {
            String name = statisticsNameMap.get(Long.valueOf(id));
            if (name != null) {
                reportName.add(name);
            }

        });
        return String.join("、", reportName);
    }

    @Override
    public List<SalaryStatisticsPushPO> getSuccessPushListByReceiver(Long uid) {
        List<Long> batchIds = getSalaryStatisticsPushDetailService(user).getSuccessPushDetailListByReceiver(uid)
                .stream().map(SalaryStatisticsPushDetailPO::getBatchId).collect(Collectors.toList());
        // 根据batchId获取分享记录
        if (CollectionUtils.isEmpty(batchIds)) {
            return Collections.emptyList();
        }
        List<SalaryStatisticsPushPO> pushList = new ArrayList<>();
        List<List<Long>> partition = Lists.partition((List<Long>)batchIds, 1000);
        partition.forEach(ids -> {
            pushList.addAll(getSalaryStatisticsPushMapper().listSome(SalaryStatisticsPushPO.builder().ids(ids).build()));
        });
        return filterReportByTime(pushList);
    }

    @Override
    public List<SalaryStatisticsPushPO> getPushListByReportIdAndIds(Long reportId, List<Long> ids) {
        List<SalaryStatisticsPushPO> pushList = getSalaryStatisticsPushMapper().listByReportIdAndIds(reportId.toString(), ids);
        pushList = pushList.stream().filter( push -> {
            return Arrays.asList(push.getReportIds().split(",")).contains(reportId.toString());
        }).collect(Collectors.toList());
        return pushList;
    }

    List<SalaryStatisticsPushPO> filterReportByTime(List<SalaryStatisticsPushPO> pushList){
        // 报表分享时间校验
        String formatLocalDateTime = SalaryDateUtil.getFormatLocalDate(LocalDateTime.now());
        List<SalaryStatisticsPushPO> result = pushList.stream().filter(pushPO -> {
            if (pushPO.getStartTime().compareTo(formatLocalDateTime) > 0 || (StringUtils.isNotEmpty(pushPO.getEndTime()) && pushPO.getEndTime().compareTo(formatLocalDateTime) < 0)) {
                return false;
            }
            return true;
        }).collect(Collectors.toList());
        return result;
    }

    @Override
    public List<SalaryStatisticsPushPO> shareReportValid(Long reportId, Long uid) {
        // 获取该员工所有被分享成功的明细
        List<SalaryStatisticsPushDetailPO> successPushDetailList = getSalaryStatisticsPushDetailService(user).getSuccessPushDetailListByReceiver(uid);
        // 根据报表id，分享批次id查询分享批次信息
        List<Long> batchIds = successPushDetailList.stream().map(SalaryStatisticsPushDetailPO::getBatchId).collect(Collectors.toList());
        List<SalaryStatisticsPushPO> pushList= getPushListByReportIdAndIds(reportId,batchIds);
        if (CollectionUtils.isEmpty(pushList)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"暂无权限查看该报表"));
        }
        // 校验是否在分享的有效时间内
        pushList = filterReportByTime(pushList);
        if (CollectionUtils.isEmpty(pushList)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0,"该报表的分享不在有效期内，无法查看"));
        }
        return pushList;
    }
}


