package com.zd.laboratory.service.impl;

import com.zd.common.core.constant.SecurityConstants;
import com.zd.common.core.constant.UserConstants;
import com.zd.common.core.domain.R;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.enums.HazardTypeEnum;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.Assert;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.laboratory.domain.LabHazardSubjectRelation;
import com.zd.laboratory.domain.LabQpSubjectRelation;
import com.zd.laboratory.domain.LabSubject;
import com.zd.laboratory.domain.dto.LabHazardJoinSubDTO;
import com.zd.laboratory.domain.vo.LabClassifiedVo;
import com.zd.laboratory.domain.vo.LabClasstypeVo;
import com.zd.laboratory.domain.vo.LabSubjectVO;
import com.zd.laboratory.mapper.LabHazardSubjectRelationMapper;
import com.zd.laboratory.mapper.LabQpSubjectRelationMapper;
import com.zd.laboratory.mapper.LabSubjectMapper;
import com.zd.laboratory.service.ILabHazardSubjectRelationService;
import com.zd.laboratory.service.ILabSubjectService;
import com.zd.system.api.RemoteUserService;
import com.zd.system.api.domain.SysUser;
import com.zd.system.api.laboratory.domain.TotalByID;
import com.zd.system.api.laboratory.domain.vo.LabSubClassVO;
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.Collections;
import java.util.List;

/**
 * 实验室Service业务层处理
 *
 * @author zd
 * @date 2021-08-30
 */
@Service
public class LabSubjectServiceImpl implements ILabSubjectService {
    @Autowired
    private LabSubjectMapper labSubjectMapper;

    @Autowired
    private RemoteUserService userService;

    @Autowired
    private ILabHazardSubjectRelationService labHazardSubjectRelationService;
    @Autowired
    private LabHazardSubjectRelationMapper labHazardSubjectRelationMapper;
    @Autowired
    private LabQpSubjectRelationMapper labQpSubjectRelationMapper;
    /**
     * 查询实验室
     *
     * @param id 实验室主键
     * @return 实验室
     */
    @Override
    public LabSubject selectLabSubjectById(Long id) {
        return labSubjectMapper.selectLabSubjectById(id);
    }

    /**
     * 查询实验室
     *
     * @param id 实验室主键
     * @return 实验室
     */
    @Override
    public LabSubjectVO selectLabSubjectVoById(Long id) {
        return labSubjectMapper.selectLabSubjectVoById(id);
    }

    @Override
    public LabSubject selectLabSubjectCheckById(Long id) {
        return labSubjectMapper.selectLabSubjectCheckById(id);
    }

    /**
     * 查询实验室列表
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    @DataScope(deptAlias = "s", permi = PerPrefix.LABORATORY_SUBJECT)
    public List<LabSubject> selectLabSubjectList(LabSubject labSubject) {
        List<LabSubject> labSubjectList = labSubjectMapper.selectLabSubjectList(labSubject);
        for(LabSubject subject:labSubjectList){
            subject.setHazardRelations(labHazardSubjectRelationService.queryHazardSubList(subject.getId()));
        }
        return labSubjectList;
    }


    /**
     * 查询登录用户是否是实验室管理员（数据权限）
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    public boolean isadmin(LabSubject labSubject) {
        List<LabSubject> labSubjects = labSubjectMapper.selectLabSubjectList(labSubject);
        if(labSubjects.size()>0){
            return true;
        }
        return false;
    }

    /**
     * 查询实验室列表-应用数据权限和实验室负责人权限
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t", subAdmin = true, permi = PerPrefix.LABORATORY_SUBJECT)
    public List<LabSubjectVO> selectLabSubjectListAUTH(LabSubject labSubject) {
        return labSubjectMapper.selectLabSubjectVOList(labSubject);
    }
    /**
     * 我管理的实验室数量 应用数据权限和实验室负责人权限
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t", subAdmin = true, permi = PerPrefix.LABORATORY_SUBJECT)
    public int myAdminSubCount(LabSubject labSubject) {
        return labSubjectMapper.myAdminSubCount(labSubject);
    }


    /**
     * 查询实验室列表-只应用数据权限
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t", permi = PerPrefix.LABORATORY_SUBJECT)
    public List<LabSubjectVO> selectLabSubjectListDataScope(LabSubject labSubject) {
        return labSubjectMapper.selectLabSubjectVOList(labSubject);
    }

    /**
     * 批量查询负责人负责的实验室
     *
     * @param ids
     * @return
     */
    public List<LabSubjectVO> selectLabSubjectListByAdminIds(Long... ids) {
        if (ids == null || ids.length == 0) return null;
        return labSubjectMapper.selectLabSubjectListByAdminIds(ids);
    }

    /**
     * 新增实验室
     *
     * @param labSubject 实验室
     * @return 结果
     */
    @Override
    public int insertLabSubject(LabSubject labSubject) {
        labSubject.setCreateTime(DateUtils.getNowDate());
        return labSubjectMapper.insertLabSubject(labSubject);
    }

    /**
     * 修改实验室
     *
     * @param labSubject 实验室
     * @return 结果
     */
    @Override
    @Transactional
    public int updateLabSubject(LabSubject labSubject) {
        labSubject.setUpdateTime(DateUtils.getNowDate());
//        if(CollectionUtils.isNotEmpty(labSubject.getHazardRelations())){
//            // 修改危险源
//            List<LabHazardSubjectRelation> hazardRelations = labSubject.getHazardRelations();
//            for (LabHazardSubjectRelation hazardRelation : hazardRelations) {
//                hazardRelation.setSubjectId(labSubject.getId());
//                if(hazardRelation.getHazardId() == null){
//                    throw new ServiceException("危险源ID 不能为空！");
//                }
//                hazardRelation.setHazardType(HazardTypeEnum.HAZARD);
//                hazardRelation.setxPoint(0L);
//                hazardRelation.setyPoint(0L);
//                hazardRelation.setId(null);
//            }
//
//            labHazardSubjectRelationService.updateBySubId(hazardRelations, labSubject.getId());
//        }else {
//            labHazardSubjectRelationMapper.deleteBySubId(labSubject.getId());
//        }


        return labSubjectMapper.updateLabSubject(labSubject);
    }

    /**
     * 修改实验室
     *
     * @param labSubject 实验室
     * @return 结果
     */
    @Override
    @Transactional
    public int editJoinHazard(LabSubject labSubject) {
        labSubject.setUpdateTime(DateUtils.getNowDate());
        if(CollectionUtils.isNotEmpty(labSubject.getHazardRelations())){
            // 修改危险源
            List<LabHazardSubjectRelation> hazardRelations = labSubject.getHazardRelations();
            for (LabHazardSubjectRelation hazardRelation : hazardRelations) {
                hazardRelation.setSubjectId(labSubject.getId());
                if(hazardRelation.getHazardId() == null){
                    throw new ServiceException("危险源ID 不能为空！");
                }
                hazardRelation.setHazardType(HazardTypeEnum.HAZARD);
                hazardRelation.setxPoint(0L);
                hazardRelation.setyPoint(0L);
                hazardRelation.setId(null);
                hazardRelation.setUserId(SecurityUtils.getUserId());
            }

            labHazardSubjectRelationService.updateBySubId(hazardRelations, labSubject.getId());
        }else {
            labHazardSubjectRelationMapper.deleteBySubId(labSubject.getId());
        }

        //气瓶数量与实验室关系录入
        LabQpSubjectRelation lsjr = new LabQpSubjectRelation();
        lsjr.setSubjectId(labSubject.getId());
        List<LabQpSubjectRelation> lsjrList = labQpSubjectRelationMapper.selectLabQpSubjectRelationList(lsjr);
        lsjr.setBottleTotal(labSubject.getBottleTotal());
        lsjr.setBottleUserTotal(labSubject.getBottleUserTotal());
        if(lsjrList.isEmpty()){
            lsjr.setCreateTime(DateUtils.getNowDate());
            lsjr.setCreateBy(SecurityUtils.getUsername());
            labQpSubjectRelationMapper.insertLabQpSubjectRelation(lsjr);
        }else{
            lsjr.setId(lsjrList.get(0).getId());
            lsjr.setUpdateTime(DateUtils.getNowDate());
            lsjr.setUpdateBy(SecurityUtils.getUsername());
            labQpSubjectRelationMapper.updateLabQpSubjectRelation(lsjr);
        }
        return labSubjectMapper.updateLabSubject(labSubject);
    }

    /**
     * 关联实验室负责人 (只有未关联实验室才可以)
     *
     * @param userID
     * @param subId
     * @return
     */
    @Override
    public int setSubjectAdmin(Long userID, Long subId) {

        if (userID != -1L) {
            //验证
            R<SysUser> user = userService.getUserInfoByUserId(userID, SecurityConstants.INNER);
            if (user.getCode() == 200 && user.getData() != null) {
                Assert.isTrue(UserConstants.USER_TYPE_TEACHER.equals(user.getData().getUserType()), "用户类型错误！");
                Assert.isTrue(UserConstants.NORMAL.equals(user.getData().getDelFlag()), "用户状态不可用！");
                Assert.isTrue(UserConstants.NORMAL.equals(user.getData().getStatus()), "用户状态不可用！");

            } else {
                throw new ServiceException("用户获取错误！");
            }
        }

        LabSubject labSubject = new LabSubject();
        labSubject.setAdminId(userID);
        labSubject.setId(subId);
        return labSubjectMapper.setSubjectAdmin(labSubject);

    }


    /**
     * 批量删除实验室
     *
     * @param ids 需要删除的实验室主键
     * @return 结果
     */
    @Override
    public int deleteLabSubjectByIds(Long[] ids) {
        return labSubjectMapper.deleteLabSubjectByIds(ids);
    }

    /**
     * 删除实验室信息
     *
     * @param id 实验室主键
     * @return 结果
     */
    @Override
    public int deleteLabSubjectById(Long id) {
        return labSubjectMapper.deleteLabSubjectById(id);
    }


    /**
     * 查询实验室字典表
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    @DataScope(deptAlias = "s" , permi = PerPrefix.LABORATORY_SUBJECT)
    public List<LabSubject> getSubjectDict(LabSubject labSubject) {
        return labSubjectMapper.getSubjectDict(labSubject);
    }

    /**
     * 查询实验室字典表
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    public List<LabSubject> getSubjectDictByViolation(LabSubject labSubject) {
        return labSubjectMapper.getSubjectDictByViolation(labSubject);
    }

    /**
     * 查询实验室字典表
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    public List<LabSubject> getFilterSubjectDict(LabSubjectVO labSubject) {
        return labSubjectMapper.getFilterSubjectDict(labSubject);
    }

    /**
     * 查询实验室根据实验室管理员用户权限过滤数据
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    public List<LabSubject> getUserRoleBySub(LabSubjectVO labSubject) {
        labSubject.setAdminId(SecurityUtils.getUserId());
        return labSubjectMapper.getUserRoleBySub(labSubject);
    }

    /**
     * 查询实验室根据实验室管理员用户权限过滤数据
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    public List<LabSubject> getUserRoleBySubBindRisk(LabSubjectVO labSubject) {
        labSubject.setAdminId(SecurityUtils.getUserId());
        return labSubjectMapper.getUserRoleBySubBindRisk(labSubject);
    }

    /**
     * 我的实验室列表
     *
     * @param labSubjectVo 实验室
     * @return 我的实验室列表
     */
    @Override
    public List<LabSubjectVO> mySubjectList(LabSubjectVO labSubjectVo) {
        return labSubjectMapper.mySubjectList(labSubjectVo);
    }

    /**
     * 获取实验室及关联信息
     *
     * @param labSubject
     * @return
     */
    @Override
    public List<LabSubject> getAllSubjectByParame(LabSubjectVO labSubject) {
        return labSubjectMapper.getAllSubjectByParame(labSubject);
    }


    /**
     * 根据实验室IDs 查询危险等级
     *
     * @param ids 实验室ids
     * @return 危险等级
     */
    @Override
    public List<LabSubClassVO> querySubClassesByIds(Long... ids) {
        if (ids == null || ids.length == 0) return null;
        return labSubjectMapper.querySubClassesByIds(ids);
    }

    /**
     * 查询实验室数量通过楼栋IDs
     *
     * @param ids
     * @return
     */
    @Override
    public List<TotalByID> queryCountByBuildIds(Long... ids) {
        if (ids == null || ids.length == 0) return Collections.emptyList();
        return labSubjectMapper.queryCountByBuildIds(ids);
    }

    /**
     * 实验室查询
     *
     * @param labSubject
     * @return
     */
    @Override
    public List<LabSubject> selectLabSubjectListSecurity(LabSubject labSubject) {
        return labSubjectMapper.selectLabSubjectListSecurity(labSubject);
    }

    /***
     * 查询有负责人的实验室
     * @param labSubject
     * @return
     */
    @Override
    public List<LabSubject> selectLabSubjectListByadminidNotnull(LabSubject labSubject) {
        return labSubjectMapper.selectLabSubjectListByadminidNotnull(labSubject);
    }


    /**
     * 查询实验室列表
     *
     * @param ids 实验室
     * @return 实验室
     */
    @Override
    public List<LabSubject> multipleDetpBysubList(Long[] ids) {
        List<LabSubject> labSubjectList = labSubjectMapper.multipleDetpBysubList(ids);
        return labSubjectList;
    }

    @Override
    public List<LabSubject> getByIds(List<Long> ids) {
        if (ids.isEmpty()){
            return Collections.emptyList();
        }
        return labSubjectMapper.getByIds(ids);
    }


    /**
     * 查询首页分类统计
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    @DataScope(deptAlias = "st", permi = PerPrefix.LABORATORY_SUBJECT)
    public List<LabClasstypeVo> getTypeCount(LabSubjectVO labSubject) {
        return labSubjectMapper.getTypeCount(labSubject);
    }


    /**
     * 查询首页分级统计
     *
     * @param labSubject 实验室
     * @return 实验室
     */
    @Override
    @DataScope(deptAlias = "st", permi = PerPrefix.LABORATORY_SUBJECT)
    public List<LabClassifiedVo> getFiedCount(LabSubjectVO labSubject) {
        return labSubjectMapper.getFiedCount(labSubject);
    }
}
