package com.yx.face.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yx.face.boot.restful.RestDTO;
import com.yx.face.boot.restful.RestResponse;
import com.yx.face.boot.restful.RestResult;
import com.yx.face.boot.restful.ServiceException;
import com.yx.face.boot.uitls.DateUtils;
import com.yx.face.boot.uitls.JsonUtils;
import com.yx.face.boot.uitls.SMSOrIdCardUtils;
import com.yx.face.dao.*;
import com.yx.face.model.dto.UserWhitelistDTO;
import com.yx.face.model.entity.*;
import com.yx.face.model.excel.UserWhitelistExcel;
import com.yx.face.model.search.UserWhitelistSearch;
import com.yx.face.model.vo.AdminVO;
import com.yx.face.model.vo.UserWhitelistVO;
import com.yx.face.service.AdminService;
import com.yx.face.service.UserBlackListService;
import com.yx.face.service.UserInfoService;
import com.yx.face.service.UserWhitelistService;
import com.yx.face.service.feign.TBDeviceFaceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.*;

/**
 * @description:
 * @ClassName UserWhitelistServiceImpl
 * @Author WXG
 * @Date 2021/11/5 14:16
 */
@Slf4j
@Service
public class UserWhitelistServiceImpl implements UserWhitelistService {

    @Autowired
    private UserInfoService userInfoService;

    @Resource
    private UserWhitelistDao userWhitelistdao;

    @Resource
    private UserBlackListService userBlackListService;

    @Resource
    private AdminService adminService;

    @Resource
    private FaceDeviceDao faceDeviceDao;

    @Resource
    private FaceRequestLogDao faceRequestLogDao;

    @Autowired
    private TBDeviceFaceService tbDeviceFaceService;

    @Resource
    private FacePassDao facePassDao;

    @Resource
    private FaceTaskDao faceTaskDao;

    @Autowired
    private AsyncTriggerRetryImpl asyncTriggerRetryImpl;

    @Override
    public Integer insert(UserWhitelistDTO userWhitelistDTO) {
        userWhitelistDTO.setId(null);
        UserWhitelist userWhitelist = getUserWhitelist(userWhitelistDTO);
        userWhitelist.setCreateTime(new Date());
        userWhitelist.setStatus(2);
        userWhitelist.setType(1);
        return userWhitelistdao.insert(userWhitelist);
    }

    @Override
    public Integer update(UserWhitelistDTO userWhitelistDTO) {
        if (userWhitelistDTO.getId() == null) {
            throw new ServiceException("修改时常客主键不能为空");
        }
        UserWhitelist userWhitelist = getUserWhitelist(userWhitelistDTO);
        userWhitelist.setId(userWhitelistDTO.getId());
        userWhitelist.setUpdateTime(new Date());
        return userWhitelistdao.updateByPrimaryKeySelective(userWhitelist);
    }

    //数据校验
    private UserWhitelist getUserWhitelist(UserWhitelistDTO userWhitelistDTO) {
        UserWhitelist userWhitelist = new UserWhitelist();
        userWhitelist.setAdminId(adminService.getInfo().getAdminId());
        //校验手机号
        if (userWhitelistDTO.getPhone() == null || userWhitelistDTO.getPhone().equals("")) {
            throw new ServiceException("手机号不能为空");
        }
        if (!SMSOrIdCardUtils.isMobile(userWhitelistDTO.getPhone())) {
            throw new ServiceException("手机号有误");
        }
        UserWhitelist byPhoneAndId = userWhitelistdao.getByPhoneAndId(userWhitelistDTO.getPhone(), userWhitelistDTO.getId(), userWhitelist.getAdminId());
        if (byPhoneAndId != null) {
            throw new ServiceException("手机号已经存在");
        }

        userWhitelist.setName(userWhitelistDTO.getName() == null ? null : userWhitelistDTO.getName());
        userWhitelist.setPhone(userWhitelistDTO.getPhone() == null ? null : userWhitelistDTO.getPhone());
        return userWhitelist;
    }


    @Override
    public Integer delete(Integer id, Integer adminId) {
//        return userWhitelistdao.deleteByPrimaryKey(id);
//        List<String> msg = new ArrayList<>();
        UserWhitelist userWhitelist = userWhitelistdao.selectByPrimaryKey(id);
        //判断白名单是否存在
        if (userWhitelist == null) {
            throw new ServiceException("该数据已不存在，请刷新页面再试哦~");
        }
//        List<String> faceDeviceNo = faceDeviceDao.selectListNo(userWhitelist.getAdminId());
//        if (!faceDeviceNo.isEmpty()) {
//            for (String s : faceDeviceNo) {
//                msg.add(s + ":设备离线或未授权或未启用");
//            }
//        }
        //获取 adminId所有设备
        List<String> faceDeviceOne = faceDeviceDao.selectList(userWhitelist.getAdminId());
        if (faceDeviceOne.isEmpty()) {
            throw new ServiceException("该设备不存在或离线，请刷新页面再试哦~");
        }
        Long userId = userWhitelistdao.setUserOne(id, userWhitelist.getAdminId());
        //获取设备 删除人脸
        for (String sn : faceDeviceOne) {
            Map<String, Object> result;
            // 1. entrySet遍历，在键和值都需要时使用（最常用）
            Map<String, Object> params = com.beust.jcommander.internal.Maps.newHashMap();
            Date now = new Date();
            List<Map<String, Object>> data = new ArrayList<>();
            Map<String, Object> userMap = com.beust.jcommander.internal.Maps.newHashMap();
            userMap.put("pin", userId);
            data.add(userMap);
            List<Long> userIds = new ArrayList<>();
            userIds.add(userId);
            params.put("Data", data);
            params.put("SN", sn);
            FaceRequestLog requestLog = new FaceRequestLog();
            requestLog.setName("删除人员人脸信息");
            requestLog.setContext("/delUser");
            requestLog.setParams(JsonUtils.toJson(params));
            requestLog.setStatus(0);
            requestLog.setUsedTime(0L);
            requestLog.setUpdateTime(now);
            requestLog.setCreateTime(now);
            params.put("taskId", requestLog.getId());
//            try {
//                result = tbDeviceFaceService.delUser(params);
//                if (!StringUtils.equals("命令下发成功", (String) result.get("msg"))) {
//                    Boolean aBoolean = userBlackListService.delUserRetry(params);
//                    if (!aBoolean) {
//                        msg.add(sn + ":设备下发失败，原因：" + (String) result.get("msg"));
//                    }
//                } else {
//                    faceRequestLogDao.insertSelective(requestLog);
//                    faceTaskDao.updateFaceTaskStatus(sn, userIds);
//                }
//                log.info("删除结果={}", result);
//            } catch (Exception e) {
//                log.info("删除人脸异常 {}", e.getMessage());
//                Boolean aBoolean = userBlackListService.delUserRetry(params);
//                if (!aBoolean) {
//                    msg.add(sn + ":设备下发失败，原因：" + e.getMessage());
//                }
//            }
//        }
            try {
                result = tbDeviceFaceService.delUser(params);
                if (!StringUtils.equals("命令下发成功", (String) result.get("msg"))) {
                    //异步下发三次
                    asyncTriggerRetryImpl.delUserRetry(params);
                } else {
                    faceRequestLogDao.insertSelective(requestLog);
                    faceTaskDao.updateFaceTaskStatus(sn, userIds);
                }
                log.info("删除结果={}", result);
            } catch (Exception e) {
                asyncTriggerRetryImpl.delUserRetry(params);
                log.info("删除人脸异常 {}", e.getMessage());
            }
        }
        userWhitelistdao.deleteByPrimaryKey(id);
//        if (!msg.isEmpty()) {
//            //判断是否删除成功
//            throw new ServiceException(msg.toString());
//        }
        return 1;
    }

    @Override
    public PageInfo<UserWhitelistVO> getPageList(RestDTO<UserWhitelistSearch> dto) {
        UserWhitelistSearch data = dto.getData();

        if (data.getPhone() != null && !data.getPhone().equals("") && (!SMSOrIdCardUtils.isMobile(data.getPhone()))) {
            throw new ServiceException("手机号查询时须填写完整");
        }
        AdminVO info = adminService.getInfo();
        Map<String, Object> map = new HashMap<>();
        map.put("adminVo", info);
        map.put("uws", dto.getData());

        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<UserWhitelistVO> list = userWhitelistdao.selectListBySearch(map);
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getPhone() != null)
                list.get(i).setPhone(SMSOrIdCardUtils.hidePhone(list.get(i).getPhone()));
            if (list.get(i).getIdNumber() != null)
                list.get(i).setIdNumber(SMSOrIdCardUtils.hideIdNumber(list.get(i).getIdNumber()));
            if (list.get(i).getName() != null)
                list.get(i).setName(SMSOrIdCardUtils.hideName(list.get(i).getName().trim()));
        }
        return new PageInfo<>(list);
    }

    @Override
    public RestResult<List<String>> uploadUserWhitelistExcel(List<Object> datas) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < datas.size(); i++) {
            try {
                UserWhitelistExcel userWhitelistExcel = (UserWhitelistExcel) datas.get(i);
                if (userWhitelistExcel.getName() == null) throw new ServiceException("第" + (i + 2) + "行,姓名不能为空");
                if (userWhitelistExcel.getPhone() == null) throw new ServiceException("第" + (i + 2) + "行,手机号不能为空");

                UserWhitelistDTO userWhitelistDTO = new UserWhitelistDTO();
                userWhitelistDTO.setName(userWhitelistExcel.getName());
                userWhitelistDTO.setPhone(userWhitelistExcel.getPhone());
                try {
                    this.insert(userWhitelistDTO);
                } catch (Exception e) {
                    throw new ServiceException("第" + (i + 2) + "行," + e.getMessage());
                }
            } catch (ServiceException e) {
                list.add(e.getMessage());
                continue;
            }
        }
        datas.clear();//结束后销毁不用的资源
        return RestResponse.ok(list);
    }

    /**
     * @param deviceId
     * @return
     */
    @Override
    public RestResult<String> addSnIssued(Integer deviceId) {
        List<String> msg = new ArrayList<>();
        RestResult<String> objectRestResult = new RestResult<>();
        //获取 adminId所有设备
        FaceDevice faceDevice = new FaceDevice();
        faceDevice.setId(deviceId);
        faceDevice.setOnline(1);
        faceDevice.setEnable(1);
        faceDevice.setAuth(1);
        FaceDevice faceDeviceOne = faceDeviceDao.selectOne(faceDevice);
        if (faceDeviceOne == null) {
            objectRestResult.setCode(401);
            objectRestResult.setMsg("设备不在线或设备未授权");
            return objectRestResult;
        }
        //人脸下发
        Date now = new Date();
        Date date = DateUtils.addYears(now, 1);
        //获取 adminId 下的常客
        List<UserWhitelistVO> list = userWhitelistdao.selectList(faceDeviceOne.getAdminId());
        for (UserWhitelistVO userWhitelist : list) {
            //判断是否有照片
            if (StringUtils.isBlank(userWhitelist.getAvatar())) {
                //记录错误信息
                msg.add(userWhitelist.getName() + ":下发失败无人脸照片");
                continue;
            } else {
                userWhitelist.setSn(faceDeviceOne.getSn());
                userWhitelist.setAdminId(faceDeviceOne.getAdminId());
                Map<String, Object> map = downFaceByTask(userWhitelist, DateUtils.addMinutes(now, -10), date, 2);
                if (!StringUtils.equals("命令下发成功", (String) map.get("msg"))) {
                    msg.add(userWhitelist.getName() + "下发失败, 原因:" + (String) map.get("msg"));
                }
            }
        }
        if (msg.isEmpty()) {
            objectRestResult.setCode(200);
            objectRestResult.setMsg("下发成功");
        } else {
            objectRestResult.setCode(200);
            objectRestResult.setMsg(msg.toString());
        }
        return objectRestResult;
    }

    @Override
    public RestResult<String> addSingle(Integer userId, Integer id) {
        List<String> msg = new ArrayList<>();
        RestResult<String> objectRestResult = new RestResult<>();

        UserWhitelistVO one = userWhitelistdao.selectListOne(id);

        List<String> faceDeviceOne = faceDeviceDao.selectList(one.getAdminId());
        if (faceDeviceOne.isEmpty()) {
            objectRestResult.setCode(401);
            objectRestResult.setMsg("设备不在线常客名单全量失败");
            return objectRestResult;
        }
        //人脸下发
        Date now = new Date();
        Date date = DateUtils.addYears(now, 1);
        one.setAdminId(userId);
        for (String s : faceDeviceOne) {
            one.setSn(s);
            Map<String, Object> map = downFaceByTask(one, DateUtils.addMinutes(now, -10), date, 2);
            if (!StringUtils.equals("命令下发成功", (String) map.get("msg"))) {
                msg.add(one.getName() + "下发失败, 原因:" + (String) map.get("msg"));
            }
        }
        if (msg.isEmpty()) {
            objectRestResult.setCode(200);
            objectRestResult.setMsg("下发成功");
        } else {
            objectRestResult.setCode(401);
            objectRestResult.setMsg(msg.toString());
        }
        return objectRestResult;
    }


    /**
     * @param whitelistVO 对应数据
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @param type        类型
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> downFaceByTask(UserWhitelistVO whitelistVO, Date startTime, Date endTime, Integer type) {
        Map<String, Object> result = new HashMap<>();
        //天波人脸服务请求日志表
        FaceRequestLog requestLog;
        Date now = new Date();
        //人脸下发表
        FacePass facePass;
        //唯一id
        Long faceTaskId;
        //人脸清除定时任务
        FaceTask faceTask;
        //信息
        String msg;
        //人脸下发到设备里面
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(3);
        List<Map<String, Object>> data = Lists.newArrayListWithExpectedSize(1);
        Map<String, Object> dataItem = Maps.newHashMapWithExpectedSize(8);
        FaceDevice faceDeviceBySn = faceDeviceDao.getFaceDeviceBySn(whitelistVO.getSn());
        // 下发参数
        dataItem.put("pin", whitelistVO.getId());
        dataItem.put("name", whitelistVO.getName());
        dataItem.put("validPeriodStart", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime));
        dataItem.put("validPeriodEnd", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime));
        dataItem.put("userType", 0);
        dataItem.put("photo", whitelistVO.getAvatar());
        dataItem.put("rightno", 105);
        dataItem.put("cardid", whitelistVO.getIdNumber());
        data.add(dataItem);
        params.put("SN", whitelistVO.getSn());
        params.put("Data", data);
        //天波人脸服务请求日志表
        requestLog = new FaceRequestLog();
        requestLog.setName("下发人脸");
        requestLog.setContext("/downUser");
        requestLog.setParams(JsonUtils.toJson(params));
        requestLog.setStatus(1);
        requestLog.setUsedTime(0L);
        requestLog.setUpdateTime(now);
        requestLog.setCreateTime(now);
        //人脸下发记录表
        faceRequestLogDao.insertSelective(requestLog);
        params.put("taskId", requestLog.getId());
        //人脸下发表
        facePass = new FacePass();
        facePass.setUserId(whitelistVO.getId());
        facePass.setDeviceSn(faceDeviceBySn.getSn());
        facePass.setDeviceId(faceDeviceBySn.getId());
        facePass.setStartTime(startTime);
        facePass.setEndTime(endTime);
        facePass.setAdminId(whitelistVO.getAdminId());
        facePass.setStatus(2);
        facePass.setType(type);
        facePass.setTaskId(whitelistVO.getAdminId().toString());
        facePass.setUpdateTime(now);
        facePass.setCreateTime(now);
        //人脸下发
        facePassDao.insertSelective(facePass);
        asyncTriggerRetryImpl.send(params, facePass);
//        try {
//            result = tbDeviceFaceService.downUser(params);
//            log.info("下发人脸downFace = {}", result);
//            if (result.get("msg") != null) {
//                msg = result.get("msg").toString();
//                if (msg.contains("不在线")) {
//                    //设备不在线 重试 3次
//                    Boolean retry = userInfoService.triggerRetry(params);
//                    if (!retry) {
//                        facePass.setStatus(3);
//                    }
//                }
//            }
//        } catch (Exception e) {
//            log.info("下发失败 原因 {}", e.getMessage());
//            //设备不在线 重试 3次
//            Boolean retry = userInfoService.triggerRetry(params);
//            if (!retry) {
//                facePass.setStatus(3);
//            }
//        }
//        //添加人脸
//        facePassDao.insertSelective(facePass);
        faceTaskId = faceTaskDao.getFaceTaskId(whitelistVO.getSn(), whitelistVO.getId());
        faceTask = new FaceTask();
        faceTask.setId(faceTaskId);
        faceTask.setTaskTime(facePass.getEndTime());
        faceTask.setStatus(0);
        faceTask.setUpdateTime(now);
        if (faceTaskId == null) {
            faceTask.setDeviceSn(whitelistVO.getSn());
            faceTask.setUserId(whitelistVO.getId());
            faceTask.setCreateTime(now);
            faceTaskDao.insertSelective(faceTask);
        }
        faceTaskDao.updateByPrimaryKeySelective(faceTask);
        return result;
    }
}
