package com.zd.laboratory.service.impl;

import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.service.TokenService;
import com.zd.laboratory.domain.LabHazard;
import com.zd.laboratory.domain.LabHazardSubjectRelation;
import com.zd.laboratory.domain.LabRiskPlan;
import com.zd.laboratory.domain.LabSafeClassified;
import com.zd.laboratory.domain.dto.LabHazardDTO;
import com.zd.laboratory.domain.dto.LabHazardNewVo;
import com.zd.laboratory.domain.vo.LabHazardBigViewVO;
import com.zd.laboratory.domain.vo.LabHazardColumnarVO;
import com.zd.laboratory.domain.vo.LabHazardVO;
import com.zd.laboratory.mapper.*;
import com.zd.laboratory.service.ILabHazardService;
import com.zd.system.api.domain.SysUser;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 危险源Service业务层处理
 *
 * @author zd
 * @date 2021-09-01
 */
@Service
public class LabHazardServiceImpl implements ILabHazardService {
    @Autowired
    private LabHazardMapper labHazardMapper;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private LabHazardSubjectRelationMapper subjectRelationMapper;
    @Autowired
    private LabRiskPlanMapper riskPlanMapper;
    @Autowired
    private LabSafeClassifiedMapper safeClassifiedMapper;

    /**
     * 查询危险源
     *
     * @param id 危险源主键
     * @return 危险源
     */
    @Override
    public LabHazard selectLabHazardById(Long id) {
        return labHazardMapper.selectLabHazardById(id);
    }

    /**
     * 查询危险源列表
     *
     * @param labHazard 危险源
     * @return 危险源
     */
    @Override
    public List<LabHazardNewVo> selectLabHazardList(LabHazard labHazard) {

        return labHazardMapper.selectLabHazardList(labHazard);
    }

    /**
     * 新增危险源
     *
     * @param labHazard 危险源
     * @return 结果
     */
    @Override
    public int insertLabHazard(LabHazard labHazard) {
        labHazard.setId(null);
        queryNameCount(labHazard);
        SysUser user = tokenService.getLoginUser().getSysUser();

        labHazard.setUserId(user.getUserId());
        labHazard.setCreateBy(user.getNickName());
        labHazard.setCreateTime(DateUtils.getNowDate());
        labHazard.setDeptId(user.getDeptId());
        labHazard.setDeptName(user.getDeptName());
        int rows = labHazardMapper.insertLabHazard(labHazard);
        //insertLabHazardSubjectRelation(labHazard);
        return rows;
    }

    /**
     * 修改危险源
     *
     * @param labHazard 危险源
     * @return 结果
     */
    @Transactional
    @Override
    @DataScope(deptAlias = "h")
    public int updateLabHazard(LabHazard labHazard) {
        queryNameCount(labHazard);
        SysUser user = tokenService.getLoginUser().getSysUser();
        labHazard.setUpdateTime(DateUtils.getNowDate());
        labHazard.setUpdateBy(user.getNickName());

        // insertLabHazardSubjectRelation(labHazard);
        return labHazardMapper.updateLabHazard(labHazard);
    }

    public void queryNameCount(LabHazard labHazard){
        int count = labHazardMapper.queryNameCount(labHazard);
        if(count > 0){
            throw new ServiceException("危险源名称已存在！");
        }
    }

    /**
     * 批量删除危险源
     *
     * @param ids 需要删除的危险源主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteLabHazardByIds(Long[] ids) {

        for (Long id : ids) {
            // 是否关联实验室
            LabHazardSubjectRelation labHazardSubjectRelation = new LabHazardSubjectRelation();
            labHazardSubjectRelation.setHazardId(id);
            if (CollectionUtils.isNotEmpty(subjectRelationMapper.selectLabHazardSubjectRelationList(labHazardSubjectRelation))) {
                throw new ServiceException("请先解除危险源和所有实验室关联关系！");
            }

            // 是否关联预案
            LabRiskPlan labRiskPlan = new LabRiskPlan();
            labRiskPlan.setHazardId(id);
            if (CollectionUtils.isNotEmpty(riskPlanMapper.selectLabRiskPlanList(labRiskPlan))) {
                throw new ServiceException("请先解除危险源和所有预案关联关系！");
            }

        }

        // labHazardMapper.deleteLabHazardSubjectRelationByIds(ids);
        return labHazardMapper.deleteLabHazardByIds(ids);
    }

    /**
     * 删除危险源信息
     *
     * @param id 危险源主键
     * @return 结果
     */
    @Override
    public int deleteLabHazardById(Long id) {
        labHazardMapper.deleteLabHazardSubjectRelationBy(id);
        return labHazardMapper.deleteLabHazardById(id);
    }

    /**
     * 查询危险源
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u", permi = PerPrefix.LABORATORY_HAZARD)
    public List<LabHazardDTO> selectLabHazardAndContainerList(LabHazardDTO labHazard) {
        List<LabHazardDTO> list = labHazardMapper.selectLabHazardAndContainerList(labHazard);
        return list;
    }

    /**
     * 新增危险源和实验室关联信息
     *
     * @param labHazard 危险源对象
     */
    public void insertLabHazardSubjectRelation(LabHazard labHazard) {
        List<LabHazardSubjectRelation> labHazardSubjectRelationList = labHazard.getLabHazardSubjectRelationList();
        Long id = labHazard.getId();
        // 先删除
        labHazardMapper.deleteLabHazardSubjectRelationBy(labHazard.getId());
        if (StringUtils.isNotNull(labHazardSubjectRelationList)) {
            List<LabHazardSubjectRelation> list = new ArrayList<LabHazardSubjectRelation>();
            for (LabHazardSubjectRelation labHazardSubjectRelation : labHazardSubjectRelationList) {
                labHazardSubjectRelation.setHazardId(id);
                list.add(labHazardSubjectRelation);
            }
            if (list.size() > 0) {
                labHazardMapper.batchLabHazardSubjectRelation(list);
            }
        }
    }


    /**
     * 查询危险源下拉框列表
     *
     * @param labHazard 危险源
     * @return 危险源下拉框列表集合
     */
    @Override
    @DataScope(deptAlias = "h")
    public List<LabHazardVO> listByHazard(LabHazard labHazard) {
        return labHazardMapper.listByHazard(labHazard);
    }

    /**
     * 危险源排名 （根据分配实验室统计）
     */
    @Override
    public List<Map<String, Object>> queryRanking(Map<String, Object> params) {
        List<Map<String, Object>> datas = labHazardMapper.queryRanking(params);

        Map<String, Object> newMap;
        List<Map<String, Object>> others;
        // 将数组下标 4到end 合并
        if (datas.size() > 4) {

            others = datas.subList(3, datas.size());
            newMap = new HashMap<>();
            newMap.put("name", "其他");
            int count = 0, labScale = 0;
            for (Map<String, Object> other : others) {
                count += Integer.parseInt(other.get("count")+"");
                labScale += Integer.parseInt(other.get("labScale")+"");
            }
            newMap.put("count", count);
            newMap.put("labScale", labScale);

            datas = datas.subList(0, 3);
            datas.add(newMap);
        }
        return datas;
    }


    /**
     * 危险源排名占比
     */
    @Override
    @DataScope(deptAlias = "t")
    public List<Map<String, Object>> queryHazardColumnar(LabHazard labHazard) {
        List<Map<String, Object>> datas = labHazardMapper.queryHazardColumnar(labHazard);
        return datas;
    }

    /**
     * 危险源排名占比
     */
    @Override
    @DataScope(deptAlias = "t")
    public List<Map<String, Object>> queryHazardColumnarTop(LabHazard labHazard) {
        List<Map<String, Object>> datas = labHazardMapper.queryHazardColumnarTop(labHazard);
        return datas;
    }

    /**
     * 危险源统计列表
     */
    @Override
    @DataScope(deptAlias = "t")
    public List<LabHazardColumnarVO> queryHazardList(LabHazardVO labHazardVO) {
        List<LabHazardColumnarVO> datas = labHazardMapper.queryHazardList(labHazardVO);
        return datas;
    }

    /**
     * 危险源统计列表
     */
    @Override
    @DataScope(deptAlias = "st", permi = PerPrefix.LABORATORY_HAZARD)
    public List<LabHazardBigViewVO> queryBigViewHazardList(LabHazardVO labHazardVO) {
        List<LabHazardBigViewVO> datas = labHazardMapper.queryBigViewHazardList(labHazardVO);
        return datas;
    }

    @Transactional
    @Override
    @DataScope(deptAlias = "h")
    public int updateLabHazardLook(LabHazard labHazard) {
        queryNameCount(labHazard);
        labHazard.setUpdateTime(DateUtils.getNowDate());
        return labHazardMapper.updateLabHazard(labHazard);
    }

}
