package com.bonus.core.customer.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.shaded.javax.annotation.Nullable;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.common.core.constant.CacheConstants;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.redis.service.RedisService;
import com.bonus.constant.LeCodeUseSceneEnum;
import com.bonus.constant.LeConstants;
import com.bonus.core.customer.constants.CustAgeEnum;
import com.bonus.core.customer.constants.PersonalStatusEnum;
import com.bonus.core.customer.dto.CustChangePasswordDTO;
import com.bonus.core.customer.dto.CustForgetPasswordDTO;
import com.bonus.core.customer.dto.CustInfoDTO;
import com.bonus.core.customer.dto.CustPayDTO;
import com.bonus.core.customer.mapper.CustInfoMapper;
import com.bonus.core.customer.service.CustInfoService;
import com.bonus.constant.RetCodeEnum;
import com.bonus.core.customer.api.CustCasualApi;
import com.bonus.core.customer.vo.CustInfoVo;
import com.bonus.core.customer.vo.CustPayVO;
import com.bonus.domain.SmsCodeVerifyDTO;
import com.bonus.domain.CustInfo;
import com.bonus.i18n.I18n;
import com.bonus.utils.AesEncryptUtil;
import com.bonus.utils.SM4EncryptUtils;
import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CustInfoServiceImpl extends ServiceImpl<CustInfoMapper, CustInfo> implements CustInfoService {
    private static final Logger log = LoggerFactory.getLogger(CustInfoServiceImpl.class);
    @Autowired
    private RedisService redisService;
    @Autowired
    @Lazy
    private CustCasualApi custCasualApi;
    @Autowired
    private CustInfoMapper custInfoMapper;

//   @Autowired
//   @Lazy
//   private CustDiningPlaceService custDiningPlaceService;

//   @Value("${customer.h5-login-default-pwd}")
//   private String h5LoginPwd;

   @Override
   public CustInfoVo queryCustInfoDetail(CustInfo custInfo) {
      CustInfoVo result = this.getNormalCustInfoDetail(custInfo);
      if (ObjectUtil.isNotNull(result)) {
         if (LeConstants.DATA_DEFAULT_INTEGER.equals(result.getSex())) {
            result.setSex((Integer)null);
         }

         if (LeConstants.DATA_DEFAULT_INTEGER.equals(result.getMaritalStatus())) {
            result.setMaritalStatus((Integer)null);
         }
      }

      return this.processCustomerDetailReturnData(result);
   }


   @Nullable
      protected CustInfoVo processCustomerDetailReturnData(CustInfoVo result) {
      if (ObjectUtil.isNull(result)) {
         return result;
      } else {
         if (ObjectUtil.isNotNull(result.getBirthday())) {
            result.setAge(CustAgeEnum.getAge(result.getBirthday()));
         }

         //里面有mqtt相关代码  先注释
//         JsonNode jsonNode = (JsonNode)this.custDiningPlaceService.getDiningPlaceMapByCustIds(Collections.singletonList(result.getCustId())).get(result.getCustId());
//         if (ObjectUtil.isNotEmpty(jsonNode)) {
//            result.setDiningPlace(jsonNode);
//         }

         return result;
      }
   }

   protected CustInfoVo getNormalCustInfoDetail(CustInfo custInfo) {
      custInfo.setCustState(PersonalStatusEnum.NORMAL.getKey());
      return custInfoMapper.queryCustInfoDetail(custInfo);
   }



    @Override
    public AjaxResult custChangePassword(CustChangePasswordDTO content) {
        AjaxResult ajaxResult = new AjaxResult();
        CustInfo custInfoQuery = new CustInfo();
        custInfoQuery.setCustId(content.getCustId());
        CustInfo custInfo = custInfoMapper.selectOne(custInfoQuery);
        if (ObjectUtil.isNull(custInfo)) {
            log.error("小程序修改密码错误：人员不存在:" + String.valueOf(custInfo));
//         throw new ServiceException("小程序修改密码错误：人员不存在");
            ajaxResult.put("msg", "小程序修改密码错误：人员不存在");
            ajaxResult.put("code", "500");
        } else {
            content.setOldPassword(AesEncryptUtil.aesDecode(content.getOldPassword()));
            content.setNewPassword(AesEncryptUtil.aesDecode(content.getNewPassword()));
            String oldPassword = content.getOldPassword();
            String newPassword = content.getNewPassword();
            if (Objects.equals(oldPassword, newPassword)) {
                log.error("小程序修改密码错误：两次密码不能一致");
                ajaxResult.put("msg", "小程序修改密码错误：两次密码不能一致");
                ajaxResult.put("code", "500");
//            throw new ServiceException("小程序修改密码错误：两次密码不能一致");
            } else {
                BCryptPasswordEncoder bCrypt = new BCryptPasswordEncoder();
                if (!bCrypt.matches(oldPassword, custInfo.getPwd())) {
                    log.error("小程序修改密码错误：原密码不正确");
                    ajaxResult.put("msg", "小程序修改密码错误：原密码不正确");
                    ajaxResult.put("code", "500");
//               throw new ServiceException("小程序修改密码错误：原密码不正确");
                } else {
                    String password = bCrypt.encode(newPassword);
                    custInfo.setPwd(password);
                    custInfoMapper.updateById(custInfo);
                    this.custCasualApi.updateLoginState(content.getCustId(), content.getOpenid());
                    ajaxResult.put("msg", "修改成功");
                    ajaxResult.put("code", "200");
                }
            }
        }
        return ajaxResult;
    }

    public static void main(String[] args) {
        BCryptPasswordEncoder bCrypt = new BCryptPasswordEncoder();
        boolean flag = bCrypt.matches("Bonus$2026", "$2a$10$vrcmG0TyvgH5tS9g8ptaVOK2K3pYWVAa13SWEK7pQBGRtNAPlGV7O");
        System.out.println(flag);
    }

    @Override
    public AjaxResult custForgetPassword(CustForgetPasswordDTO content) {
//      content.setMobile(AesEncryptUtil.aesDecode(content.getMobile()));
        AjaxResult ajaxResult = new AjaxResult();
        content.setNewPassword(AesEncryptUtil.aesDecode(content.getNewPassword()));
        SmsCodeVerifyDTO smsCodeVerifyDTO = new SmsCodeVerifyDTO();
        smsCodeVerifyDTO.setTelephoneNumber(content.getMobile());
        smsCodeVerifyDTO.setCode(content.getCode());
        if (!verifySmsCode(smsCodeVerifyDTO, CacheConstants.VERIFICATION_CODE)) {
//            throw new ServiceException("验证码异常");
            ajaxResult.put("msg", "验证码异常");
            ajaxResult.put("code", "500");
        } else {
            CustInfo custInfoQuery = new CustInfo();
            custInfoQuery.setMobile(SM4EncryptUtils.sm4Encryptbyconfig(content.getMobile()));
            CustInfo custInfo = custInfoMapper.selectOne(custInfoQuery);
            if (ObjectUtil.isNull(custInfo)) {
                log.error("修改密码错误：人员不存在:" + custInfo);
//                throw new ServiceException("修改密码错误：人员不存在", RetCodeEnum.PAY_PERSONAL_NO_EXIT.getKey());
                ajaxResult.put("msg", "修改密码错误：人员不存在");
                ajaxResult.put("code", "500");
            } else {
                String newPassword = content.getNewPassword();
                BCryptPasswordEncoder bCrypt = new BCryptPasswordEncoder();
                String password = bCrypt.encode(newPassword);
                custInfo.setPwd(password);
                custInfoMapper.updateById(custInfo);
                ajaxResult.put("msg", "修改成功");
                ajaxResult.put("code", "200");
            }
        }
        return ajaxResult;
    }

    public boolean verifySmsCode(SmsCodeVerifyDTO smsCodeVerifyDTO, String cacheKey) {
        String key = cacheKey + smsCodeVerifyDTO.getTelephoneNumber();
        String code = redisService.getCacheObject(key); //RedisUtil.getString(key);
        log.info("redis缓存验证码code : {}", code);
        return ObjectUtil.isNotEmpty(code) && ObjectUtil.equal(code, smsCodeVerifyDTO.getCode());
    }

    @Override
    public String getOrderQRCode(Integer sourceType, String paramValue) {
        String stime = String.valueOf(System.currentTimeMillis() / 1000L);
        return "xnzn{\"s\":" + sourceType + ",\"y\":" + LeCodeUseSceneEnum.PAY.key() + ",\"p\":\"" + paramValue + "\",\"t\":" + stime + "}";
    }

    @Override
    public CustInfoVo queryCustInfo(CustInfoDTO record) {
        if (Objects.isNull(record.getCustState())) {
            record.setCustState(PersonalStatusEnum.NORMAL.getKey());
        }

        return ((CustInfoMapper)this.baseMapper).queryCustInfo(record);
    }

    @Override
    public CustPayVO getCustPayVO(CustPayDTO custPayDTO) {
        log.info("获取支付所需人员，custPayDTO={}", JSONUtil.toJsonStr(custPayDTO));
        if (!Objects.isNull(custPayDTO) && (!CharSequenceUtil.isBlank(custPayDTO.getSerialNum()) || !CharSequenceUtil.isBlank(custPayDTO.getOpenid()) || !Objects.isNull(custPayDTO.getCustId()))) {
            List<CustPayVO> custPayVoList = ((CustInfoMapper)this.baseMapper).getCustPayVO(custPayDTO);
            if (CollUtil.isEmpty(custPayVoList)) {
                throw new ServiceException("人员不存在");
            } else {
                List<CustPayVO> custList = (List)custPayVoList.stream().filter((e) -> {
                    return PersonalStatusEnum.NORMAL.getKey().equals(e.getCustState());
                }).collect(Collectors.toList());
                if (CollUtil.isEmpty(custList)) {
                    throw new ServiceException("customer.customer.cancel");
                } else {
                    if (custList.size() > 1) {
                        log.info("查询记录:{}", JSON.toJSONString(custPayVoList));
                    }

                    log.info("获取支付所需人员{}", ((CustPayVO)custList.get(0)).getCustName());
                    return (CustPayVO)custList.get(0);
                }
            }
        } else {
            throw new ServiceException("参数错误！");
        }
    }

    @Override
    public void updateCustPhotoUrl(Long custId, String cutPhotoUrl) {
        ((CustInfoMapper)this.baseMapper).update(null, Wrappers.<CustInfo>lambdaUpdate()
                .eq(CustInfo::getCustId, custId)
                .set(CustInfo::getCustPhotoUrl, cutPhotoUrl));
    }
}
