package com.zd.smartlock.service.impl;

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.StringUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.log.annotation.Log;
import com.zd.common.security.service.TokenService;
import com.zd.smartlock.domain.SlOpendoorApply;
import com.zd.smartlock.domain.SlSubjectRelation;
import com.zd.smartlock.domain.SlUserRelation;
import com.zd.smartlock.domain.api.SlUser;
import com.zd.smartlock.domain.vo.SlOpendoorApplyVo;
import com.zd.smartlock.domain.vo.SlSubjectRelationVo;
import com.zd.smartlock.mapper.SlOpendoorApplyMapper;
import com.zd.smartlock.mapper.SlSubjectRelationMapper;
import com.zd.smartlock.mapper.SlUserRelationMapper;
import com.zd.smartlock.service.ISlOpendoorApplyService;
import com.zd.smartlock.service.ISlUserRelationService;
import com.zd.smartlock.utils.SmartlockUtil;
import com.zd.system.api.RemoteUserService;
import com.zd.system.api.chemical.RemoteStockService;
import com.zd.system.api.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 申请开门Service业务层处理
 *
 * @author zd
 * @date 2022-09-03
 */
@Slf4j
@Service
public class SlOpendoorApplyServiceImpl implements ISlOpendoorApplyService {
    @Autowired
    private SlOpendoorApplyMapper slOpendoorApplyMapper;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SlSubjectRelationMapper slSubjectRelationMapper;

    @Autowired
    private RemoteStockService remoteStockService;

    /**
     * 查询申请开门
     *
     * @param id 申请开门主键
     * @return 申请开门
     */
    @Override
    public SlOpendoorApply selectSlOpendoorApplyById(Long id) {
        return slOpendoorApplyMapper.selectSlOpendoorApplyById(id);
    }

    /**
     * 查询申请开门列表
     *
     * @param slOpendoorApply 申请开门
     * @return 申请开门
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u", permi = PerPrefix.SMARTLOCK_OPENDOORAPPLY)
    public List<SlOpendoorApplyVo> selectSlOpendoorApplyList(SlOpendoorApplyVo slOpendoorApply) {
        return slOpendoorApplyMapper.selectSlOpendoorApplyList(slOpendoorApply);
    }

    /**
     * 查询申请开门列表-学生端
     *
     * @param slOpendoorApply 申请开门
     * @return 申请开门集合
     */
    @Override
    public List<SlOpendoorApplyVo> selectSlOpendoorApplyListStudent(SlOpendoorApplyVo slOpendoorApply) {
        return slOpendoorApplyMapper.selectSlOpendoorApplyList(slOpendoorApply);
    }

    @Override
    public List<SlOpendoorApply> getListByIds(List<Long> ids) {
        if (ids.isEmpty()) {
            new ArrayList<>();
        }
        return slOpendoorApplyMapper.getListByIds(ids);
    }

    /**
     * 新增申请开门
     *
     * @param slOpendoorApply 申请开门
     * @return 结果
     */
    @Override
    //@Transactional(rollbackFor = Exception.class)
    public int insertSlOpendoorApply(SlOpendoorApply slOpendoorApply) {

        SysUser sysUser = tokenService.getLoginUser().getSysUser();

        //1.校验实验室是否配置并且关联双锁
        SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
        subjectRelation.setSubjectId(slOpendoorApply.getSubjectId());
        List<SlSubjectRelationVo> subjectList = slSubjectRelationMapper.selectSlSubjectRelationList(subjectRelation);
        if (subjectList.size() < 2) {
            throw new ServiceException("该实验室关联门锁不足2个！");
        }
        //2.校验人员电话是否为空
        if (StringUtils.isEmpty(sysUser.getPhonenumber())) {
            throw new ServiceException("申请人：" + sysUser.getNickName() + "电话为空！");
        }

        if (StringUtils.isEmpty(slOpendoorApply.getSafeUserPhone())) {
            throw new ServiceException("实验室负责人：" + slOpendoorApply.getSafeUserName() + "电话为空！");
        }

        slOpendoorApply.setUserId(sysUser.getUserId());
        slOpendoorApply.setUserName(sysUser.getNickName());
        slOpendoorApply.setDeptId(sysUser.getDept().getDeptId());
        slOpendoorApply.setDeptName(sysUser.getDept().getDeptName());
        slOpendoorApply.setUserCode(sysUser.getUserName());
        slOpendoorApply.setUserSex(sysUser.getSex() == null ? 1 : Integer.valueOf(sysUser.getSex()));
        slOpendoorApply.setPhonenumber(sysUser.getPhonenumber());
        slOpendoorApply.setCreatTime(new Date());
        slOpendoorApplyMapper.insertSlOpendoorApply(slOpendoorApply);
        try {
            //授权并且发送短信通知实验室门锁对应的安全负责人
           String msg=  authPowerNew(slOpendoorApply.getId());
           log.info("授权或者短信通知结果："+msg);
        } catch (Exception e) {
            log.info("授权失败："+e);
        }
        return 1;
    }

    /**
     * 修改申请开门
     *
     * @param slOpendoorApply 申请开门
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSlOpendoorApply(SlOpendoorApply slOpendoorApply) {
        return slOpendoorApplyMapper.updateSlOpendoorApply(slOpendoorApply);
    }

    /**
     * 批量删除申请开门
     *
     * @param ids 需要删除的申请开门主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSlOpendoorApplyByIds(Long[] ids) {
        return slOpendoorApplyMapper.deleteSlOpendoorApplyByIds(ids);
    }

    /**
     * 删除申请开门信息
     *
     * @param id 申请开门主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSlOpendoorApplyById(Long id) {
        return slOpendoorApplyMapper.deleteSlOpendoorApplyById(id);
    }


    /***
     * 门锁申请重新授权
     * @param id
     * @return
     */
    @Override
    public String againAuth(Long id) {
        String str="";
        try {
            str =  authPowerNew(id);
        }catch (Exception e) {
            e.printStackTrace();
            log.error("重新授权失败："+e);
        }
        return str;
    }

    /***
     * 审批通过后人员密码授权处理
     * @param applyId 申请id
     */
    public String authPowerNew(Long applyId) throws Exception {
        log.info("========开始门锁授权===========");
        //人员1 授权结果
        Boolean auths1=false;
        //返回值
        String strMsg="ok";
        try {
            //查询申请记录
            SlOpendoorApply opendoorApply = slOpendoorApplyMapper.selectSlOpendoorApplyById(applyId);

            SlSubjectRelationVo subjectRelation = new SlSubjectRelationVo();
            subjectRelation.setSubjectId(opendoorApply.getSubjectId());
            List<SlSubjectRelationVo>  listsubRla = slSubjectRelationMapper.selectSlSubjectRelationList(subjectRelation);
            if(listsubRla.size()!=2){
                strMsg="该实验室暂未绑定双锁！";
            }

            Map<String,Object> detalisMap = new HashMap<>();
            SlUser user = new SlUser();
            //学号、工号
            user.setPersoncode(opendoorApply.getUserCode());
            //姓名
            user.setPersonname(opendoorApply.getUserName());
            //性别 （0=女，1=男）
            user.setPersonsex(opendoorApply.getUserSex()==null?1+"":0+"");
            //人员类别（1=学生，2=教职工，3=临时人员）
            user.setPersontype("1");
            //电话
            user.setPersonmobile(opendoorApply.getPhonenumber());
            log.info("=======人员1授权开始========");
            Map<String,Object> map1= SmartlockUtil.addUser(user,listsubRla.get(0).getLockRoomId());

            if(!SmartlockUtil.resultMsg.equals(map1.get("resultMsg").toString())){
                log.info("人员："+opendoorApply.getUserName()+"，授权失败，原因："+map1.get("resultMsg")+"，请联系管理员");
                strMsg="人员："+opendoorApply.getUserName()+"，授权失败，原因："+map1.get("resultMsg")+"，请联系管理员";
                return strMsg;
            }else {
                log.info("=======人员1授权成功========");
                auths1=true;
            }

            log.info("=======授权结束========人员授权结果:"+auths1);
            //人员入住办理成功,发送短信提示
            if(auths1){
                SlSubjectRelationVo relationVo = new SlSubjectRelationVo();
                relationVo.setSubjectId(opendoorApply.getSubjectId());
                List<SlSubjectRelationVo> relist = slSubjectRelationMapper.selectSlSubjectRelationList(relationVo);
                if(relist.size()<2){
                    log.info("该实验室暂未关联双门锁。");
                    throw  new ServiceException("该实验室暂未关联双门锁。");
                }

                for (SlSubjectRelationVo rvo:relist) {
                    if(opendoorApply.getSafeUserId().equals(String.valueOf(rvo.getSubjectId())) ){
                        log.info("=============授权成功，下发短信================");
                        //人员1 备注详情
                        detalisMap.put("人员",opendoorApply.getUserName());
                        detalisMap.put("锁编号",rvo.getLockCode());
                        detalisMap.put("人员密码",map1.get("password"));

                        R r1= remoteStockService.sendSydSms(
                                "【实验室安全系统】" + opendoorApply.getUserName() + "申请" +
                                        opendoorApply.getSubjectName() +
                                        "-门禁远程授权，手机号："+opendoorApply.getPhonenumber()+"，授权码："+map1.get("password")+
                                        "（"+ SmartlockUtil.authsLength+"小时内有效），请勿泄露给他人。",
                                3, opendoorApply.getId(), rvo.getSafeUserPhone());
                        log.info("人员1短信发送结果："+r1);
                    }
                }
            }
            opendoorApply.setIllustrate(detalisMap.toString());
            slOpendoorApplyMapper.updateSlOpendoorApply(opendoorApply);

        }catch (Exception e){
            log.info("=======人员授权失败========"+e);
        }
        return strMsg;
    }
}
