package com.kmall.admin.service.impl.faceid;

import com.google.common.collect.ImmutableBiMap;
import com.kmall.admin.dao.*;
import com.kmall.admin.dto.FaceByOrderDto;
import com.kmall.admin.dto.SendTempDto;
import com.kmall.admin.entity.*;
import com.kmall.admin.fromcomm.dao.SysConfigDao;
import com.kmall.admin.fromcomm.entity.SysUserEntity;
import com.kmall.admin.service.UserService;
import com.kmall.admin.service.faceid.FaceIdService;
import com.kmall.admin.utils.ShiroUtils;
import com.kmall.manager.dao.TemplateConfDao;
import com.kmall.manager.dto.FaceIdRequestDto;
import com.kmall.common.constant.Dict;
import com.kmall.common.utils.*;
import com.kmall.manager.entity.pay.TemplateConfVo;
import com.kmall.manager.manager.faceid.FaceCheckUtil;
import com.kmall.manager.manager.wechat.wxtemplate.TemplateData;
import com.kmall.manager.manager.wechat.wxtemplate.WxTemplate;
import com.kmall.manager.manager.wechat.wxtemplate.WxTemplateUtil;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author huangyq
 * @version 1.0
 * 2019-11-27 14:14
 */
@Service("faceIdService")
public class FaceIdServiceImpl implements FaceIdService {
    private static Log logger = LogFactory.getLog(FaceIdServiceImpl.class);
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderGoodsDao orderGoodsDao;
    @Autowired
    private MerchDao merchDao;
    @Autowired
    private ThirdMerchantBizDao thirdMerchantBizDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private TemplateConfDao templateConfDao;
    @Autowired
    private FaceLivenessRecognitionReturnDataDao faceLivenessRecognitionReturnDataDao;
    @Autowired
    private UserService userService;
    @Autowired
    private SysConfigDao sysConfigDao;

    /**
     * 人脸认证
     * @param faceByOrderDto
     * @return
     */
    @Override
    public String checkLivenessRecognition(FaceByOrderDto faceByOrderDto){
        Map<String, Object> valideDate = MapBeanUtil.fromObject(faceByOrderDto);
        ImmutableBiMap.Builder builder = new ImmutableBiMap.Builder();
        builder.put("idCard", "身份证号");
        builder.put("name", "姓名");
        builder.put("videoBase64", "视频的BASE64值");
        builder.put("orderId", "订单id");
        R r = ValidatorUtil.isEmpty(builder.build(), valideDate);
        if (Integer.valueOf(r.get("code").toString()) != 0) {
            throw new RRException(r.get("msg").toString());
        }
        OrderEntity orderEntity = orderDao.queryObject(faceByOrderDto.getOrderId());
        if(orderEntity == null){
            throw new RRException("订单不存在！");
        }
        Map map = userService.checkFaceTimeByUserId(Long.valueOf(String.valueOf(orderEntity.getUserId())));
        boolean isCheck = (boolean)map.get("isCheck");
        Date addSecondTime = (Date)map.get("addSecondTime");//人脸识别认证失效时间
        if(!isCheck){
            throw new RRException("该订单的用户在"+DateUtils.format(addSecondTime,DateUtils.DATE_TIME_PATTERN)+"时间前可不再进行人脸识别");
        }
        MerchEntity merchEntity = merchDao.findByMerchSn(orderEntity.getMerchSn());
        if(merchEntity == null){
            throw new RRException("商户不存在");
        }
        ThirdMerchantBizEntity thirdMerchantBizEntity = thirdMerchantBizDao.queryThirdDataByStoreId(orderEntity.getStoreId());
        if(thirdMerchantBizEntity == null){
            throw new RRException("该订单门店的第三方商户不存在");
        }

        FaceIdRequestDto faceIdRequestDto = new FaceIdRequestDto();
        faceIdRequestDto.setLivenessType(Dict.livenessType.item_SILENT.getItem());
        faceIdRequestDto.setIdCard(faceByOrderDto.getIdCard());
        faceIdRequestDto.setName(faceByOrderDto.getName());
        faceIdRequestDto.setVideoBase64(faceByOrderDto.getVideoBase64());
        faceIdRequestDto.setMerchId(orderEntity.getMerchSn());
        faceIdRequestDto.setMerchName(merchEntity.getMerchName());
        faceIdRequestDto.setThirdPartyMerchCode(thirdMerchantBizEntity.getThirdPartyMerchCode());
        faceIdRequestDto.setThirdPartyMerchName(thirdMerchantBizEntity.getThirdPartyMerchName());
        ResponseData responseData = FaceCheckUtil.checkLivenessRecognition(faceIdRequestDto);
        FaceLivenessRecognitionReturnDataEntity returnDataEntity = faceLivenessRecognitionReturnDataDao.getFaceByOrderSn(orderEntity.getOrderSn());
        if(!responseData.getCode().equalsIgnoreCase("0")){
            //更新验证活体人脸核身接口返回的数据记录表中的是否验证成功为已验证，通知模板为未通知
            if(returnDataEntity != null) {
                int failCount = returnDataEntity.getFailCount()==null?0:returnDataEntity.getFailCount();
                updateFaceLivenessRecognition(orderEntity.getOrderSn(), "0", failCount, responseData.getMsg());
            }
            throw new RRException(responseData.getMsg());
        }else{//人脸核验成功
            Map faceIdResponseDto = (Map)responseData.getData().getRows().get(0);
            //保存用户表中的最后活体人脸核身时间
            UserEntity user = new UserEntity();
            user.setId(orderEntity.getUserId());
            if(StringUtils.isNotEmpty((String)faceIdResponseDto.get("returnTime"))) {
                user.setLastFaceTime((String)faceIdResponseDto.get("returnTime"));
            }
            userDao.update(user);
            //更新验证活体人脸核身接口返回的数据记录表中的是否验证成功为已验证，通知模板为未通知
            if(returnDataEntity != null) {
                updateFaceLivenessRecognition(orderEntity.getOrderSn(), "1", null, responseData.getMsg());
            }
            return responseData.getMsg();
        }
    }

    @Override
    public String sendWxTemp(long orderId){
        TemplateConfVo templateConfVo =
                templateConfDao.queryByTypeId(10); //  模板类型 10待支付提醒
        if (null == templateConfVo) {
            return "";
        }
        SendTempDto sendTempDto = orderDao.queryOrderByRecogTemp(orderId);
        if(sendTempDto != null) {
            Map map = new HashMap();
            map.put("orderId", orderId);
            List<OrderGoodsEntity> orderGoodsEntityList = orderGoodsDao.queryList(map);
            StringBuffer goodsNames = new StringBuffer();
            if(orderGoodsEntityList.size()>0){
                for(OrderGoodsEntity goodsEntity: orderGoodsEntityList){
                    goodsNames.append(goodsEntity.getGoodsName() + ",");
                }
            }
            Date add_time = sendTempDto.getAddTime();
            String open_id = sendTempDto.getOpenId();
            String goods_name = goodsNames.toString().substring(0, goodsNames.length() - 1);
            String order_sn = sendTempDto.getOrderSn();
            String addTime = "";
            if (add_time != null) {
                addTime = DateUtils.format(add_time, DateUtils.DATE_TIME_PATTERN);
            }
            WxTemplate tem = new WxTemplate();
            tem.setTemplate_id(templateConfVo.getTemplateId());
            tem.setTouser(open_id);
            tem.setPage("/pages/ucenter/orderDetail/orderDetail?id=" + orderId);

            List<TemplateData> paras = new ArrayList<TemplateData>();
            String addTimeAfter = DateUtils.addMin(add_time, 15);
            String desc = templateConfVo.getDesc().replace("addTimeAfter", addTimeAfter);
            paras.add(new TemplateData("thing1", goods_name));
            paras.add(new TemplateData("date2", addTime));
            paras.add(new TemplateData("thing3", desc));
            tem.setData(paras);
            JSONObject jsonObject = WxTemplateUtil.sendMessage(tem);
            int result = jsonObject.getInt("errcode");
            String resultmsg = jsonObject.getString("errmsg");
            if (result != 0) {
                String error = "";
                if (result == 43101) {
                    error = "用户openId【" + open_id + "】待支付提醒模板推送失败，原因：用户拒绝接受消息，如果用户之前曾经订阅过，则表示用户取消了订阅关系";
                    logger.info(error);
                } else if (result == 40037) {
                    error = "用户openId【" + open_id + "】待支付提醒模板推送失败，原因：订阅模板id为空不正确";
                    logger.info(error);
                } else if (result == 41030) {
                    error = "用户openId【" + open_id + "】待支付提醒模板推送失败，原因：page路径不正确，需要保证在现网版本小程序中存在，与app.json保持一致";
                    logger.info(error);
                } else {
                    error = resultmsg;
                    logger.info(error);
                }
                Map param = new HashMap();
                param.put("orderSn", order_sn);
                param.put("isTempNoti", 0);
                param.put("tempNotiMsg", error);
                faceLivenessRecognitionReturnDataDao.updateOrderByTempNoti(param);
                return error;
            } else {
                Map param = new HashMap();
                param.put("orderSn", order_sn);
                param.put("isTempNoti", 1);
                param.put("tempNotiMsg", "通知成功");
                faceLivenessRecognitionReturnDataDao.updateOrderByTempNoti(param);
                return "通知成功";
            }
        }
        return "通知成功";
    }

    /**
     * 更新订单人脸认证记录表
     * @param orderSn
     * @param isFaceCheck
     * @param msg
     */
    private void updateFaceLivenessRecognition(String orderSn,String isFaceCheck, Integer failCount, String msg){
        FaceLivenessRecognitionReturnDataEntity entity = new FaceLivenessRecognitionReturnDataEntity();
        entity.setOrderSn(orderSn);
        entity.setIsFaceCheck(isFaceCheck);
        entity.setIsTempNoti("0");//未通知
        entity.setRecognitionReturnMsg(msg);
        if(failCount != null) {
            entity.setFailCount(failCount + 1);
        }
        entity.setCheckOperatorType(Dict.checkOperatorType.item_1.getItem());
        faceLivenessRecognitionReturnDataDao.updateByMerchOrderSn(entity);
    }

    public String manualCheckFace(long orderId){
        SysUserEntity user = ShiroUtils.getUserEntity();
        OrderEntity orderEntity = orderDao.queryObject(orderId);
        if(orderEntity != null) {
            FaceLivenessRecognitionReturnDataEntity faceLivenessRecognitionReturnDataEntity = faceLivenessRecognitionReturnDataDao.getFaceByOrderSn(orderEntity.getOrderSn());
            if(faceLivenessRecognitionReturnDataEntity != null) {
                FaceLivenessRecognitionReturnDataEntity entity = new FaceLivenessRecognitionReturnDataEntity();
                entity.setId(faceLivenessRecognitionReturnDataEntity.getId());
                entity.setCheckOperatorType(Dict.checkOperatorType.item_2.getItem());
                entity.setCheckOperatorSn(user.getUsername());
                entity.setCheckOperatorTime(new Date());
                entity.setIsFaceCheck("1");
                faceLivenessRecognitionReturnDataDao.update(entity);
            }else{
                return "审核失败！订单人脸识别数据不存在";
            }
        }else{
            return "审核失败！订单不存在";
        }
        return "审核成功";
    }

    public FaceLivenessRecognitionReturnDataEntity get(long id){
        return faceLivenessRecognitionReturnDataDao.queryObject(id);
    }
}
