package com.zd.laboratory.service.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.core.web.domain.AjaxResult;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.service.TokenService;
import com.zd.common.security.utils.SaveUtil;

import com.zd.laboratory.domain.LabMessageDynamic;
import com.zd.laboratory.domain.LabSecurityMaterialrelation;
import com.zd.laboratory.domain.vo.LabSecurityApplyVO;
import com.zd.laboratory.mapper.LabSecurityMaterialrelationMapper;
import com.zd.laboratory.service.ILabMessageDynamicService;
import com.zd.laboratory.service.ILabMessageUserService;
import com.zd.system.api.RemoteUserService;
import com.zd.system.api.domain.SysUser;
import com.zd.system.api.exam.RemoteExamService;
import com.zd.system.api.laboratory.domain.LabMessageUser;
import com.zd.system.api.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zd.laboratory.mapper.LabSecurityApplyMapper;
import com.zd.laboratory.domain.LabSecurityApply;
import com.zd.laboratory.service.ILabSecurityApplyService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;

/**
 * 安全准入申请Service业务层处理
 *
 * @author zd
 * @date 2022-01-24
 */
@Service
public class LabSecurityApplyServiceImpl implements ILabSecurityApplyService
{
    @Autowired
    private LabSecurityApplyMapper labSecurityApplyMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private LabSecurityMaterialrelationMapper labSecurityMaterialrelationMapper;

    @Autowired
    private RemoteExamService remoteExamService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private ILabMessageDynamicService labMessageDynamicService;

    @Autowired
    private ILabMessageUserService labMessageUserService;

    private static final Logger log = LoggerFactory.getLogger(LabSecurityApplyServiceImpl.class);

    /**
     * 查询安全准入申请
     *
     * @param id 安全准入申请主键
     * @return 安全准入申请
     */
    @Override
    public LabSecurityApplyVO selectLabSecurityApplyById(Long id)
    {
        return labSecurityApplyMapper.selectLabSecurityApplyById(id);
    }

    /**
     * 查询安全准入申请列表
     *
     * @param labSecurityApplyVO 安全准入申请
     * @return 安全准入申请
     */
    @Override
    //@DataScope(deptAlias = "t" , userAlias = "t" , permi = PerPrefix.LABORATORY_APPLY)
    public List<LabSecurityApplyVO> selectLabSecurityApplyList(LabSecurityApplyVO labSecurityApplyVO)
    {
        return labSecurityApplyMapper.selectLabSecurityApplyList(labSecurityApplyVO);
    }

    /***
     * 根据日期排序查询
     * @param labSecurityApplyVO
     * @return
     */
    @Override
    @DataScope(deptAlias = "t" , userAlias = "t" , permi = PerPrefix.LABORATORY_APPLY)
    public List<LabSecurityApplyVO> selectLabSecurityApplyListYmd(LabSecurityApplyVO labSecurityApplyVO) {
        return labSecurityApplyMapper.selectLabSecurityApplyListYmd(labSecurityApplyVO);
    }

    /**
     * 新增安全准入申请
     *
     * @param labSecurityApply 安全准入申请
     * @return 结果
     */
    @Override
    public int insertLabSecurityApply(LabSecurityApply labSecurityApply)
    {
        return labSecurityApplyMapper.insertLabSecurityApply(labSecurityApply);
    }

    /**
     * 修改安全准入申请
     *
     * @param labSecurityApply 安全准入申请
     * @return 结果
     */
    @Override
    public int updateLabSecurityApply(LabSecurityApply labSecurityApply)
    {
        //获取登录用户信息
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        if(1==labSecurityApply.getAuditStatus()){
        //驳回
            labSecurityApply.setRejectTime(new Date());//驳回时间

            //查询审批记录信息
            LabSecurityApply labSecurityApplyNew = labSecurityApplyMapper.selectLabSecurityApplyById(labSecurityApply.getId());

            //驳回消息他通知
            LabMessageDynamic labMessageDynamic = new LabMessageDynamic();
            labMessageDynamic.setSendRange(3);
            labMessageDynamic.setMessClass(1);
            labMessageDynamic.setContent(labSecurityApply.getRejectCause());
            labMessageDynamic.setDynamicId(labSecurityApply.getId());
            int dynamicId = labMessageDynamicService.insertLabMessageDynamic(labMessageDynamic);
            if(dynamicId>0){
                LabMessageUser labMessageUser = new LabMessageUser();
                labMessageUser.setJoinUserId(labSecurityApplyNew.getUserId());
                labMessageUser.setIsRead(false);
                labMessageUser.setMessageId(labMessageDynamic.getId());
                labMessageUserService.insertLabMessageUser(labMessageUser);
            }

        }else if(2==labSecurityApply.getAuditStatus()){
            //通过
            labSecurityApply.setAuditName(sysUser.getNickName());
            labSecurityApply.setAuditId(sysUser.getUserId());
            labSecurityApply.setAuditTime(new Date());

            //查询该条记录的详情
            LabSecurityApplyVO applyVO= labSecurityApplyMapper.selectLabSecurityApplyById(labSecurityApply.getId());

            if(UserConstants.USER_TYPE_STUDENT.equals(applyVO.getUserType())){
                //为学生时初始化分值
                List<Map<String, Object>> cerlist= labSecurityApplyMapper.selectUserCertList(applyVO.getUserId());
                Map<String,Object> initMap = new HashMap<>();
                initMap.put("joinUserId",applyVO.getUserId());
                initMap.put("nickName",applyVO.getUserName());
                initMap.put("userName",applyVO.getUserNumber());
                initMap.put("gainSafeCert",cerlist.size()>0?1:0);
                initMap.put("gainSubSafeCert",1);
                initMap.put("reason","获取实验室安全准入资格");
                remoteExamService.initCreditPoints(initMap);
            }
        }
        labSecurityApply.setUpdateTime(DateUtils.getNowDate());
        labSecurityApply.setUpdateBy(SecurityUtils.getUsername());
        return labSecurityApplyMapper.updateLabSecurityApply(labSecurityApply);
    }

    /**
     * 批量删除安全准入申请
     *
     * @param ids 需要删除的安全准入申请主键
     * @return 结果
     */
    @Override
    public int deleteLabSecurityApplyByIds(Long[] ids)
    {
        return labSecurityApplyMapper.deleteLabSecurityApplyByIds(ids);
    }

    /**
     * 删除安全准入申请信息
     *
     * @param id 安全准入申请主键
     * @return 结果
     */
    @Override
    public int deleteLabSecurityApplyById(Long id)
    {
        return labSecurityApplyMapper.deleteLabSecurityApplyById(id);
    }

    /***
     * 安全申请提交
     * @param labSecurityApplyVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int materialAdd(LabSecurityApplyVO labSecurityApplyVO) {


        //获取登录用户信息
        SysUser sysUser = tokenService.getLoginUser().getSysUser();

        //学生信息非空校验
        if(StringUtils.isBlank(labSecurityApplyVO.getSysUser().getNickName())
                || StringUtils.isBlank(labSecurityApplyVO.getSysUser().getPhonenumber())
                || StringUtils.isBlank(labSecurityApplyVO.getSysUser().getUserName())
                || StringUtils.isBlank(labSecurityApplyVO.getSysUser().getCardNum())
                || StringUtils.isBlank(labSecurityApplyVO.getSysUser().getGrade())
                || StringUtils.isBlank(labSecurityApplyVO.getSysUser().getTutorUserId()+"")
        ){
             throw new ServiceException("请补充相关信息后在提交申请！");
        }else{
            //查看是否有信息变动，如果有更新用户信息
            if(!labSecurityApplyVO.getSysUser().getNickName().equals(sysUser.getNickName())
                    || !labSecurityApplyVO.getSysUser().getPhonenumber().equals(sysUser.getPhonenumber())
                    || !labSecurityApplyVO.getSysUser().getUserName().equals(sysUser.getUserName())
                    || !labSecurityApplyVO.getSysUser().getCardNum().equals(sysUser.getCardNum())
                    || !labSecurityApplyVO.getSysUser().getGrade().equals(sysUser.getGrade())
                    || !labSecurityApplyVO.getSysUser().getTutorUserId().equals(sysUser.getTutorUserId())
            ){
                //更新用户信息
                AjaxResult ajax=remoteUserService.editStudent(labSecurityApplyVO.getSysUser());
                System.out.println(ajax);
                String str = JSON.toJSONString(ajax);
                JSONObject json = JSON.parseObject(str);
                if(500==json.getInteger("code")){
                    throw new ServiceException(json.getString("msg"));
                }
                //根据id查询用户信息
                R<SysUser> rDate =remoteUserService.getUserInfoByUserId(labSecurityApplyVO.getSysUser().getUserId(), SecurityConstants.INNER);
                SysUser  sysUser1 = rDate.getData();
                //刷新redis缓存
                LoginUser loginUser = new LoginUser();
                tokenService.getLoginUser().setSysUser(sysUser1);
                BeanUtils.copyProperties(tokenService.getLoginUser(),loginUser);
                loginUser.setSysUser(sysUser1);
                tokenService.setLoginUser(loginUser);
            }
        }

        //获取登录用户信息
        //SysUser sysUser = tokenService.getLoginUser().getSysUser();
        labSecurityApplyVO.setUserId(sysUser.getUserId());
        labSecurityApplyVO.setUserName(sysUser.getNickName());
        labSecurityApplyVO.setUserType(sysUser.getUserType());
        labSecurityApplyVO.setDeptId(sysUser.getDept().getDeptId());
        labSecurityApplyVO.setDeptName(sysUser.getDept().getDeptName());
        labSecurityApplyVO.setCreatTime(new Date());
        labSecurityApplyVO.setUserMajor(sysUser.getMajor());
        labSecurityApplyVO.setUserMajorId(sysUser.getMajorId());
        labSecurityApplyVO.setUserNumber(sysUser.getUserName());
        //申请项录入
        int id= labSecurityApplyMapper.insertLabSecurityApply(labSecurityApplyVO);

        if(labSecurityApplyVO.getMrList()!=null && labSecurityApplyVO.getMrList().size()>0){
            //申请资料录入
            for (LabSecurityMaterialrelation lmr : labSecurityApplyVO.getMrList()) {
                lmr.setApplyId(labSecurityApplyVO.getId());
                lmr.setUserId(sysUser.getUserId());
                lmr.setCreateTime(new Date());
                labSecurityMaterialrelationMapper.insertLabSecurityMaterialrelation(lmr);
            }
        }
        return id;
    }

    /***
     * 安全申请修改
     * @param labSecurityApplyVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int materialUpdate(LabSecurityApplyVO labSecurityApplyVO) {
        //获取登录用户信息
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        labSecurityApplyVO.setUserId(sysUser.getUserId());
        labSecurityApplyVO.setUserName(sysUser.getNickName());
        labSecurityApplyVO.setUserType(sysUser.getUserType());
        //labSecurityApplyVO.setCreatTime(new Date());
        //申请项录入
        int id= labSecurityApplyMapper.updateLabSecurityApply(labSecurityApplyVO);

        //删除附件
        labSecurityMaterialrelationMapper.deleteLabSecurityMaterialrelationByApplyId(labSecurityApplyVO.getId());

        //申请资料录入
        for (LabSecurityMaterialrelation lmr : labSecurityApplyVO.getMrList()) {
            lmr.setApplyId(labSecurityApplyVO.getId());
            lmr.setUserId(sysUser.getUserId());
            lmr.setCreateTime(new Date());
            labSecurityMaterialrelationMapper.insertLabSecurityMaterialrelation(lmr);
        }

        return id;
    }

    /***
     * 查询用户证数信息
     * @param userId
     * @return
     */
    @Override
    public List<Map<String, Object>> selectUserCertList(Long userId) {
        return labSecurityApplyMapper.selectUserCertList(userId);
    }

    /**
     * 实验室负责人信息
     *
     * @param userId
     * @return
     */
    @Override
    public List<Map<String, Object>> selectLabsubjectUserInfo(Long userId) {
        return labSecurityApplyMapper.selectLabsubjectUserInfo(userId);
    }

    /***
     * 根据时间分组查询
     * @return
     * @param labSecurityApplyVO
     */
    @Override
    @DataScope(deptAlias = "t" , userAlias = "t" , permi = PerPrefix.LABORATORY_APPLY)
    public List<LabSecurityApplyVO> selectLabSecurityApplyListOrderBydate(LabSecurityApplyVO labSecurityApplyVO) {
        return labSecurityApplyMapper.selectLabSecurityApplyListOrderBydate(labSecurityApplyVO);
    }

    /**
     * 校级详情校级列表统计
     *
     * @param labSecurityApplyVO
     * @return
     */
    @Override
    @DataScope(deptAlias = "t" , userAlias = "t" , permi = PerPrefix.LABORATORY_APPLY)
    public List<LabSecurityApplyVO> selectApplyListSchool(LabSecurityApplyVO labSecurityApplyVO) {
        //获取登录用户信息
        //SysUser sysUser = tokenService.getLoginUser().getSysUser();
        //labSecurityApplyVO.setDeptId(sysUser.getDept().getDeptId());
        return labSecurityApplyMapper.selectApplyListSchool(labSecurityApplyVO);
    }

    /***
     * 安全准入校级柱形图
     * @param labSecurityApply
     * @return
     */
    @Override
    @DataScope(deptAlias = "t" , userAlias = "t" , permi = PerPrefix.LABORATORY_APPLY)
    public List<Map<String, Object>> selectApplyListSchoolColumn(LabSecurityApply labSecurityApply) {
        //获取登录用户信息
        //SysUser sysUser = tokenService.getLoginUser().getSysUser();
        //labSecurityApply.setDeptId(sysUser.getDept().getDeptId());
        return labSecurityApplyMapper.selectApplyListSchoolColumn(labSecurityApply);
    }

    /**
     * 院级详情列表统计
     *
     * @param labSecurityApplyVO
     * @return
     */
    @Override
    @DataScope(deptAlias = "t" , userAlias = "t" , permi = PerPrefix.LABORATORY_APPLY)
    public List<LabSecurityApplyVO> selectApplyListCollege(LabSecurityApplyVO labSecurityApplyVO) {
        return labSecurityApplyMapper.selectApplyListCollege(labSecurityApplyVO);
    }

    /***
     * 安全准入院级柱形图
     * @param labSecurityApply
     * @return
     */
    @Override
    @DataScope(deptAlias = "t" , userAlias = "t" , permi = PerPrefix.LABORATORY_APPLY)
    public List<Map<String, Object>> selectApplyListCollegelColumn(LabSecurityApply labSecurityApply) {
        return labSecurityApplyMapper.selectApplyListCollegelColumn(labSecurityApply);
    }



    /**
     * 根据文件，进行压缩，批量下载
     * @param response
     * @param files
     * @throws Exception
     */
    @Override
    public void downloadBatchByFile(HttpServletResponse response, Map<String, byte[]> files, String zipName){
        try{
            response.setContentType("application/x-msdownload");
            response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(zipName, "utf-8"));

            ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
            BufferedOutputStream bos = new BufferedOutputStream(zos);

            for(Map.Entry <String, byte[]> entry : files.entrySet()){
                String fileName = entry.getKey();            //每个zip文件名
                byte[]    file = entry.getValue();            //这个zip文件的字节

                BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(file));
                zos.putNextEntry(new ZipEntry(fileName));

                int len = 0;
                byte[] buf = new byte[10 * 1024];
                while( (len=bis.read(buf, 0, buf.length)) != -1){
                    bos.write(buf, 0, len);
                }
                bis.close();
                bos.flush();
            }
            bos.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /***
     * 查询审核通过未过期的申请集合
     * @param labSecurityApplyVO
     * @return
     */
    @Override
    public List<LabSecurityApplyVO> selectApplyListEffective(LabSecurityApplyVO labSecurityApplyVO) {
        return labSecurityApplyMapper.selectApplyListEffective(labSecurityApplyVO);
    }

    /***
     * 根据申请id删除附件
     * @param id
     * @return
     */
    @Override
    public int deleteLabSecurityMaterialrelationByApplyId(Long id) {
        return labSecurityMaterialrelationMapper.deleteLabSecurityMaterialrelationByApplyId(id);
    }

    /***
     * 校验申请时间是否有重叠
     * @param labSecurityApplyVO
     * @return
     */
    @Override
    public List<LabSecurityApplyVO> selectLabSecurityApplyListByTime(LabSecurityApplyVO labSecurityApplyVO) {
        return labSecurityApplyMapper.selectLabSecurityApplyListByTime(labSecurityApplyVO);
    }
}
