package com.artfess.device.base.manager.impl;

import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.device.base.dao.AppraiseBaseDao;
import com.artfess.device.base.manager.AppraiseBaseManager;
import com.artfess.device.base.manager.AppraiseItemsManager;
import com.artfess.device.base.model.AppraiseBase;
import com.artfess.device.base.model.AppraiseItems;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

/**
 * 绩效考核-考核基本信息（device_appraise_base） 服务实现类
 *
 * @author Limuhua
 * @company 阿特菲斯信息技术有限公司
 * @since 2022-08-02
 */
@Service
public class AppraiseBaseManagerImpl extends BaseManagerImpl<AppraiseBaseDao, AppraiseBase> implements AppraiseBaseManager {

    @Autowired
    private AppraiseItemsManager itemsManager;

    @Override
    public PageList<AppraiseBase> query(QueryFilter<AppraiseBase> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        QueryWrapper<AppraiseBase> queryWrapper = convert2Wrapper(queryFilter, currentModelClass());
        IPage<AppraiseBase> result = baseMapper.queryPage(convert2IPage(pageBean), queryWrapper);
        List<AppraiseItems> items = itemsManager.list();
        result.getRecords().forEach(r -> {
            List<AppraiseItems> itemsList = Lists.newArrayList();
            items.forEach(i -> {
                if (i.getBaseId().equals(r.getId())) {
                    itemsList.add(i);
                }
            });
            r.setItemsList(itemsList);
        });
        return new PageList<>(result);
    }

    @Override
    public boolean publish(AppraiseBase t) {
        Assert.notNull(t, "参数不能为空！");
        Assert.notNull(t.getId(), "ID不能为空！");
        Assert.notNull(t.getPublishStatus(), "状态不能为空！");
        return update(new UpdateWrapper<AppraiseBase>().eq("id_", t.getId()).set("publish_status_", t.getPublishStatus()));
    }

    @Override
    public boolean save(AppraiseBase t) {
        checkWeight(t.getItemsList());
        boolean result = super.save(t);
        t.getItemsList().forEach(il -> {
            il.setBaseId(t.getId());
        });
        itemsManager.saveBatch(t.getItemsList());
        return result;
    }

    @Override
    public boolean updateById(AppraiseBase t) {
        checkWeight(t.getItemsList());
        boolean result = super.updateById(t);
        t.getItemsList().forEach(il -> {
            il.setBaseId(t.getId());
        });
        itemsManager.saveOrUpdateBatch(t.getItemsList());
        return result;
    }

    @Override
    public AppraiseBase getById(Serializable id) {
        AppraiseBase result = super.getById(id);
        result.setItemsList(itemsManager.list(new QueryWrapper<AppraiseItems>().eq("base_id_", result.getId())));
        return result;
    }

    /**
     * 检查权重，权重之和不能大于需在[0,1]之间
     *
     * @param items 考核项信息
     */
    private void checkWeight(List<AppraiseItems> items) {
        // 前端已限制数据不能有负数
        BigDecimal weight = items.stream().map(AppraiseItems::getItemVal).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (weight.compareTo(new BigDecimal(1)) > 0 || weight.compareTo(new BigDecimal(0)) < 0){
            throw new RuntimeException("权重配置异常，当前权重和为【"+weight.toPlainString()+"】，权重和应落于区间 [0, 1] 中");
        }
    }

}
