package com.zd.laboratory.service.impl;

import com.zd.common.core.constant.SecurityConstants;
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.datascope.annotation.DataScope;
import com.zd.common.security.service.TokenService;
import com.zd.laboratory.domain.LabOnepc;
import com.zd.laboratory.domain.LabSubjectAccessRecord;
import com.zd.laboratory.domain.vo.LabSubjectAccessRecordVo;
import com.zd.laboratory.mapper.LabSubjectAccessRecordMapper;
import com.zd.laboratory.mapper.LabViolationMapper;
import com.zd.laboratory.mqtt.enums.BigViewDataType;
import com.zd.laboratory.mqtt.service.impl.SubMessageSendManager;
import com.zd.laboratory.service.ILabOnepcService;
import com.zd.laboratory.service.ILabPhotoInspectionService;
import com.zd.laboratory.service.ILabSubjectAccessRecordService;
import com.zd.system.api.RemoteUserService;
import com.zd.system.api.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 实验室进出记录Service业务层处理
 *
 * @author zd
 * @date 2021-08-30
 */
@Service
public class LabSubjectAccessRecordServiceImpl implements ILabSubjectAccessRecordService {
    @Autowired
    private LabSubjectAccessRecordMapper labSubjectAccessRecordMapper;

    @Autowired
    private ILabPhotoInspectionService labPhotoInspectionService;

    @Autowired
    private ILabOnepcService labOnepcService;
    @Autowired
    private TokenService tokenService;

    @Autowired
    private LabViolationMapper labViolationMapper;
    @Autowired
    private SubMessageSendManager subMessageSendManager;

    @Autowired
    private RemoteUserService userService;

    /**
     * 查询实验室进出记录
     *
     * @param id 实验室进出记录主键
     * @return 实验室进出记录
     */
    @Override
    public LabSubjectAccessRecord selectLabSubjectAccessRecordById(Long id) {
        return labSubjectAccessRecordMapper.selectLabSubjectAccessRecordById(id);
    }


    /**
     * 检查完成更新记录
     *
     * @param id id
     * @return 结构
     */
    @Override
    public boolean updateCheck(Long id) {
        return labSubjectAccessRecordMapper.updateCheck(id)==1;
    }

    /**
     * 查询实验室进出记录列表
     *
     * @param labSubjectAccessRecord 实验室进出记录
     * @return 实验室进出记录
     */
    @Override
    @DataScope(deptAlias = "re" , permi = PerPrefix.LABORATORY_RECORD)
    public List<LabSubjectAccessRecordVo> selectLabSubjectAccessRecordList(LabSubjectAccessRecordVo labSubjectAccessRecord) {
        labSubjectAccessRecord.setInitFlag(false);
        return labSubjectAccessRecordMapper.selectLabSubjectAccessRecordList(labSubjectAccessRecord);
    }

    /**
     * 查询实验室进出记录列表- 无权限
     *
     * @param labSubjectAccessRecord 实验室进出记录
     * @return 实验室进出记录集合
     */
    @Override
    public List<LabSubjectAccessRecordVo> selectLabSubjectAccessRecordListNoAuth(LabSubjectAccessRecordVo labSubjectAccessRecord) {
        return labSubjectAccessRecordMapper.selectLabSubjectAccessRecordList(labSubjectAccessRecord);
    }

    /**
     * 查询我的实验室进出记录列表
     *
     * @param labSubjectAccessRecord 实验室进出记录
     * @return 实验室进出记录
     */
    @Override
    public List<LabSubjectAccessRecordVo> selectMyAccessRecordList(LabSubjectAccessRecordVo labSubjectAccessRecord) {
        labSubjectAccessRecord.setInitFlag(false);
        return labSubjectAccessRecordMapper.selectMyAccessRecordList(labSubjectAccessRecord);
    }


    /**
     * 新增实验室进出记录
     *
     * @param labSubjectAccessRecord 实验室进出记录
     * @return 结果
     */
    @Override
    public long insertLabSubjectAccessRecord(LabSubjectAccessRecord labSubjectAccessRecord) {
        labSubjectAccessRecord.setAccessStatus(1L);
        labSubjectAccessRecord.setCreateTime(DateUtils.getNowDate());
        return labSubjectAccessRecordMapper.insertLabSubjectAccessRecord(labSubjectAccessRecord);
    }

    /**
     * 修改实验室进出记录
     *
     * @param labSubjectAccessRecord 实验室进出记录
     * @return 结果
     */
    @Override
    public int updateLabSubjectAccessRecord(LabSubjectAccessRecord labSubjectAccessRecord) {
        labSubjectAccessRecord.setUpdateTime(DateUtils.getNowDate());
        return labSubjectAccessRecordMapper.updateLabSubjectAccessRecord(labSubjectAccessRecord);
    }

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

    /**
     * 删除实验室进出记录信息
     *
     * @param id 实验室进出记录主键
     * @return 结果
     */
    @Override
    public int deleteLabSubjectAccessRecordById(Long id) {
        return labSubjectAccessRecordMapper.deleteLabSubjectAccessRecordById(id);
    }

    /**
     * 统计人员出入实验室次数(以日为单位)。
     *
     * @return 统计人员出入实验室次数
     */
    @Override
    public List<LabSubjectAccessRecordVo> labInoutTime(LabSubjectAccessRecordVo labSubjectAccessRecordVo) {
        labSubjectAccessRecordVo.setInitFlag(false);
        return labSubjectAccessRecordMapper.labInoutTime(labSubjectAccessRecordVo);
    }


    /**
     * 查询实验室进出记录
     *
     * @param id 实验室进出记录主键
     * @return 实验室进出记录
     */
    @Override
    public LabSubjectAccessRecordVo myAccessDetail(Long id) {
        LabSubjectAccessRecordVo accessVo = labSubjectAccessRecordMapper.myAccessDetail(id);
//        LabPhotoInspection inspection = new LabPhotoInspection();
//        inspection.setAccessId(accessVo.getId());
//        List<LabPhotoInspection> inspectionList = labPhotoInspectionService.selectLabPhotoInspectionList(inspection);
//        accessVo.setPhotoList(inspectionList);
        LabOnepc onePc = new LabOnepc();
        onePc.setAccessId(accessVo.getId());
        List<LabOnepc> onePcList = labOnepcService.selectLabOnepcList(onePc);
        boolean realOk = true;
        for (LabOnepc onepc : onePcList) {
            if (onepc.getOneConfirm() != null && onepc.getOneConfirm().equals("0")) {
                realOk = false;
            }
        }
        if (realOk) {
            accessVo.setOneConfirm("已完成");
        } else {
            accessVo.setOneConfirm("未完成");
        }
        return accessVo;
    }


    /**
     * 定时器定时查询离开时间超过24小时，记违规
     *
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int outTimeRecord() {
        labSubjectAccessRecordMapper.outTimeRecord();
        int i = labSubjectAccessRecordMapper.outTimeChangeStatus();
        if(i>0)
        {
            subMessageSendManager.SendBigViewUpdate(BigViewDataType.SUB_ONLINE);
        }
        return i;
    }

    /**
     * 离开实验室打卡
     *
     * @param subId
     * @param userId
     * @return
     */
    @Override
    public Boolean out(Long subId, Long userId) {
        LabSubjectAccessRecord subjectAccessRecord = new LabSubjectAccessRecord();
        subjectAccessRecord.setSubjectId(subId);
        subjectAccessRecord.setJoinUserId(userId);
        subjectAccessRecord.setOutTime(DateUtils.getNowDate());
        subMessageSendManager.SendBigViewUpdate(BigViewDataType.SUB_ONLINE);
        return labSubjectAccessRecordMapper.updateOut(subjectAccessRecord) == 1;
    }

    /**
     * 是否有正常签到记录
     *
     * @param subId
     * @param userId
     * @return
     */
    @Override
    public Boolean isSigIn(Long subId, Long userId) {
        LabSubjectAccessRecord subjectAccessRecord = new LabSubjectAccessRecord();
        subjectAccessRecord.setSubjectId(subId);
        subjectAccessRecord.setJoinUserId(userId);
        subjectAccessRecord.setInitFlag(false);
        LabSubjectAccessRecord labSubjectAccessRecordVo = labSubjectAccessRecordMapper.queryLastByUserId(subjectAccessRecord);
        if (labSubjectAccessRecordVo != null) {
            if (labSubjectAccessRecordVo.getAccessStatus().equals(1L) && labSubjectAccessRecordVo.getOutTime() == null) {
                return true;
            }

        }

        return false;
    }

    /**
     * 是否有有效签到信息并获取
     * @param userId
     * @return
     */
    @Override
    public LabSubjectAccessRecordVo isSigInAndGet(Long userId) {
        LabSubjectAccessRecordVo subjectAccessRecord = new LabSubjectAccessRecordVo();

        subjectAccessRecord.setJoinUserId(userId);
        subjectAccessRecord.setAccessStatus(1L);
        subjectAccessRecord.setInitFlag(false);
        List<LabSubjectAccessRecordVo> labSubjectAccessRecordVos = labSubjectAccessRecordMapper.selectLabSubjectAccessRecordList(subjectAccessRecord);
        return Optional.ofNullable(labSubjectAccessRecordVos)
                .filter(a->a.size()>0)
                .map(a->a.get(0))
                .orElseGet(()->null);
    }

    /**
     * 获取离开实验室拍照附件列表
     * @param userId
     * @return
     */
    @Override
    public List<LabSubjectAccessRecordVo> isSigInAndGetList(Long userId) {
        LabSubjectAccessRecordVo subjectAccessRecord = new LabSubjectAccessRecordVo();
        subjectAccessRecord.setJoinUserId(userId);
        subjectAccessRecord.setAccessStatus(1L);
        subjectAccessRecord.setInitFlag(false);
        List<LabSubjectAccessRecordVo> labSubjectAccessRecordVos = labSubjectAccessRecordMapper.selectLabSubjectAccessRecordList(subjectAccessRecord);
        return labSubjectAccessRecordVos;
    }

    /**
     * 是否有有效签到信息并获取
     * @param userId
     * @return
     */
    @Override
    public LabSubjectAccessRecordVo isSigInAndGet(Long userId,Long subject) {
        LabSubjectAccessRecordVo subjectAccessRecord = new LabSubjectAccessRecordVo();

        subjectAccessRecord.setJoinUserId(userId);
        subjectAccessRecord.setAccessStatus(1L);
        subjectAccessRecord.setInitFlag(false);
        subjectAccessRecord.setSubjectId(subject);
        List<LabSubjectAccessRecordVo> labSubjectAccessRecordVos = labSubjectAccessRecordMapper.selectLabSubjectAccessRecordList(subjectAccessRecord);
        return Optional.ofNullable(labSubjectAccessRecordVos)
                .filter(a->a.size()>0)
                .map(a->a.get(0))
                .orElseGet(()->null);
    }

    /**
     * 打卡，（离开实验室未再次进入其他实验室打卡，记违规）
     *
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public long leaveAgainSign(LabSubjectAccessRecordVo labSubjectAccessRecord) throws ServiceException {
        labSubjectAccessRecord.setAccessStatus(1L);
        labSubjectAccessRecord.setInitFlag(false);
        List<LabSubjectAccessRecordVo> accessList = labSubjectAccessRecordMapper.selectLabSubjectAccessRecordList(labSubjectAccessRecord);
        long i = 0;
        if (accessList.size() > 0) {
//            throw new ServiceException("当前用户已经签到成功，不能重复签到");
            //这里不要了，因为现在实验室需求要求，可以不同实验室打卡进入，要求当前实验室不能重复打卡
//            List<SysDictData> dictDataList = DictUtils.getDictCache(Constants.SYS_DICT_KEY + "lab_violation_rules");
//            LabSubjectAccessRecord access = accessList.get(0);
//            LabViolation labViolation = new LabViolation();
//            labViolation.setJoinUserId(access.getJoinUserId());
//            labViolation.setViolationType(1L);
//            labViolation.setViolationContent(DictUtils.getDictCacheLable("lab_violation_rules","1"));
//            labViolation.setSubjectId(access.getSubjectId());
//            labViolation.setCreateTime(new Date());
//            labViolation.setDeptName(access.getDeptName());
//            labViolation.setDeptId(access.getDeptId());
//            labViolation.setUserId(access.getUserId());
//            labViolation.setCreateBy(access.getCreateBy());
//            labViolationMapper.insertLabViolation(labViolation);
//            access.setAccessStatus(3L);
//            labSubjectAccessRecordMapper.updateLabSubjectAccessRecord(access);
        }else{
            labSubjectAccessRecord.setInTime(new Date());
            subMessageSendManager.SendBigViewUpdate(BigViewDataType.SUB_ONLINE);
            i = insertLabSubjectAccessRecord(labSubjectAccessRecord);
        }
        return i;
    }

    /**
     * 个人工作台 实验室进出统计
     */
    @Override
    public Map<String, Object> recordStatistics() {
        LabSubjectAccessRecordVo labSubjectAccessRecord = new LabSubjectAccessRecordVo();
        labSubjectAccessRecord.setUserId(SecurityUtils.getUserId());
        labSubjectAccessRecord.setInitFlag(false);
        return labSubjectAccessRecordMapper.queryRecordStatistics(labSubjectAccessRecord);
    }

    @Override
    @Transactional
    public R addRecord(Map map) {
       Long userId = Long.valueOf(map.get("userId").toString());
        R<SysUser> user = userService.getUserInfoByUserId(userId, SecurityConstants.FROM_SOURCE);
      /*  LabSubjectAccessRecord record = new LabSubjectAccessRecord();
        record.setAccessStatus();
        record.setSubjectId();
        record.setOutTime();
        record.setSubjectId(map.get(""));
        record*/
        return null;
    }

    @Override
    public int getRecordNoOut(Long userId) {
        String dateTime=DateUtils.getDate();
        return labSubjectAccessRecordMapper.getRecordNoOut(userId,dateTime);
    }

    @Override
    public int updateLabSubjectAccessRecordById(LabSubjectAccessRecord accessRecord) {
        return labSubjectAccessRecordMapper.updateLabSubjectAccessRecordById(accessRecord);
    }
}
