package com.huimv.modular.analysis.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huimv.core.context.login.LoginContextHolder;
import com.huimv.core.enums.CommonStatusEnum;
import com.huimv.core.exception.ServiceException;
import com.huimv.core.pojo.login.SysLoginUser;
import com.huimv.modular.analysis.entity.RegionAndStock;
import com.huimv.modular.analysis.enums.AnalysisExceptionEnum;
import com.huimv.modular.analysis.param.AnalysisParam;
import com.huimv.modular.analysis.service.AnalysisService;
import com.huimv.modular.dailytabulatedata.entity.DailyTabulateData;
import com.huimv.modular.dailytabulatedata.service.DailyTabulateDataService;
import com.huimv.sys.core.enums.AdminTypeEnum;
import com.huimv.sys.modular.org.entity.SysOrg;
import com.huimv.sys.modular.org.service.SysOrgService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 数据分析service接口实现类
 * </p>
 *
 * @author yinhao
 * @date 2021/8/18 15:35
 */
@Service("analysisService")
public class AnalysisServiceImpl implements AnalysisService {

    @Resource
    private SysOrgService sysOrgService;

    @Resource
    private DailyTabulateDataService dailyTabulateDataService;

    @Override
    public RegionAndStock getChildPigStockByOrgId(AnalysisParam analysisParam) {
        //检查参数,返回当前组织的子级组织列表
        List<Long> childOrgIdList = checkParam(analysisParam);

        //超级管理员查询全部,非超级管理员根据数据范围查询
        SysLoginUser sysLoginUser = LoginContextHolder.me().getSysLoginUser();
        if (!sysLoginUser.getAdminType().equals(AdminTypeEnum.SUPER_ADMIN.getCode())) {
            List<Long> dataScopes = sysLoginUser.getDataScopes();
            childOrgIdList = (List<Long>) CollUtil.intersection(childOrgIdList, dataScopes);
        }

        //判断子级组织和数据范围的交集是否为空
        RegionAndStock regionAndStock = new RegionAndStock();
        if (CollUtil.isEmpty(childOrgIdList)) {
            regionAndStock.setRegionList(CollUtil.newArrayList());
            regionAndStock.setStockList(CollUtil.newArrayList());
            return regionAndStock;
        }

        //将交集放入条件查询
        LambdaQueryWrapper<DailyTabulateData> dailyTabulateDataQuery = Wrappers.lambdaQuery();
        dailyTabulateDataQuery.in(DailyTabulateData::getOrgId,childOrgIdList);

        //查询数据列表,分组,返回时间最新的数据
        List<DailyTabulateData> dataList = dailyTabulateDataService.list(dailyTabulateDataQuery);
        Collection<DailyTabulateData> values = dataList.stream()
                .collect(Collectors.toMap(DailyTabulateData::getOrgId,
                        dailyTabulateData -> dailyTabulateData,
                        (dailyTabulateData, dailyTabulateData2)
                                -> dailyTabulateData.getStatisticDate().getTime() > dailyTabulateData2.getStatisticDate().getTime() ? dailyTabulateData : dailyTabulateData2))
                .values();

        regionAndStock.setRegionList(values.stream().map(DailyTabulateData::getOrgName).collect(Collectors.toList()));
        regionAndStock.setStockList(values.stream().map(DailyTabulateData::getStockTotal).collect(Collectors.toList()));

        return regionAndStock;
    }

    private List<Long> checkParam(AnalysisParam analysisParam) {
        Long orgId = analysisParam.getOrgId();
        LambdaQueryWrapper<SysOrg> queryWrapperById = Wrappers.lambdaQuery();
        queryWrapperById.eq(SysOrg::getId, orgId)
                .ne(SysOrg::getStatus, CommonStatusEnum.DELETED.getCode());
        //判断是否存在
        int countById = sysOrgService.count(queryWrapperById);
        if (countById <= 0) {
            throw new ServiceException(AnalysisExceptionEnum.NOT_EXIST);
        }
        //判断是否有子级组织
        queryWrapperById.clear();
        queryWrapperById.eq(SysOrg::getPid, orgId)
                .ne(SysOrg::getStatus, CommonStatusEnum.DELETED.getCode());
        List<SysOrg> sysOrgList = sysOrgService.list(queryWrapperById);
        if (CollUtil.isEmpty(sysOrgList)) {
            throw new ServiceException(AnalysisExceptionEnum.NO_CHILD);
        }
        return sysOrgList.stream().map(SysOrg::getId).collect(Collectors.toList());
    }
}
