package com.bohuikeji.delivery.backstage.controller.api.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bohuikeji.delivery.backstage.constants.WxAppEm;
import com.bohuikeji.delivery.backstage.entity.TCustomer;
import com.bohuikeji.delivery.backstage.entity.TOrder;
import com.bohuikeji.delivery.backstage.entity.TOrderCircu;
import com.bohuikeji.delivery.backstage.entity.TPay;
import com.bohuikeji.delivery.backstage.entity.baidu.BaiDuConfig;
import com.bohuikeji.delivery.backstage.entity.baidu.BaiduPayReq;
import com.bohuikeji.delivery.backstage.entity.baidu.BaiduRefundInfo;
import com.bohuikeji.delivery.backstage.entity.wx.TWxUser;
import com.bohuikeji.delivery.backstage.listener.pay.BaiDuListener;
import com.bohuikeji.delivery.backstage.service.*;
import com.bohuikeji.frame.module.admin.base.ApiController;
import com.bohuikeji.frame.module.admin.component.MqTool;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import com.bohuikeji.frame.module.admin.entity.back.APIEntity;
import com.bohuikeji.frame.module.admin.service.ISysConfigService;
import com.bohuikeji.frame.module.admin.utils.JwtTokenUtil;
import com.bohuikeji.frame.module.admin.utils.baidu.RSASign;
import com.bohuikeji.frame.module.admin.utils.baidu.baiduUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jodd.http.HttpRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * @author zhouliwu
 * 客户百度小程序相关接口
 */
@Slf4j
@Api(tags = {"客户百度小程序相关接口"})
@RestController
@RequestMapping("/api/baidu")
@RequiredArgsConstructor
public class BaiduApi extends ApiController {
    @Autowired
    ITOrderService itOrderService;
    @Autowired
    ITPayService payService;
    @Autowired
    ITCustomerService customerService;
    @Autowired
    ITOrderService orderService;
    @Autowired
    ITRefundService refundService;
    @Autowired
    ITCustomerAddressService itCustomerAddressService;
    @Autowired
    ISysConfigService sysConfigService;
    @Autowired
    ITCourierService courierService;
    @Autowired
    ITNewsService newsService;
    @Autowired
    IWxUserService wxUserService;
    @Autowired
    IGmsService gmsService;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    MqTool tool;

    /**
     * 请求百度服务器获取sessionKey
     *
     * @param code Authorization Code
     * @return
     */
    @ApiOperation("百度小程序登陆获取用户信息")
    @GetMapping("/getSessionKey")
    public APIEntity getSessionKey(String code) {
        String url = "https://spapi.baidu.com/oauth/jscode2sessionkey";
            Map<String, String> data = new HashMap<>();
            //code是前端会传的
            data.put("code", code);
            data.put("client_id", BaiDuConfig.APP_KEY);
            data.put("sk", BaiDuConfig.APP_SECRET);
            String resultJson = HttpRequest.get(url).query(data).send().bodyText();
            JSONObject res= JSONObject.parseObject(resultJson);
            log.info("登陆返回：[{}]",res);
        // 获取参数返回的
            String sessionKey = res.get("session_key").toString();
            String openId = res.get("openid").toString();
          /*  if (res != null && StringUtils.isNotBlank(res.get("openid").toString())) {
                //当获取到百度小程序的user openID后记得保存user
            }*/
        TWxUser wxUser=wxUserService.getOne(new QueryWrapper<TWxUser>().eq("wx_user_openid",openId).eq("wx_app_name","客户端小程序（百度）"));
        TCustomer customer=new TCustomer();
        if(wxUser ==null){
            wxUser = new TWxUser();
            customer = customerService.saveCustomer("百度小程序");
            wxUser.setUserId(Long.valueOf(customer.getCustomerId()));
            wxUser.setUserType(WxAppEm.WX_USER_TYPE_CUSTOMER);
            wxUser.setWxAppId(BaiDuConfig.App_ID);
            wxUser.setWxAppType("BAIDU");
            wxUser.setWxAppName("客户端小程序（百度）");
            wxUser.setWxUserOpenid(openId);
            wxUserService.save(wxUser);
        }else {
            TCustomer tCustomer = customerService.getById(wxUser.getUserId());
            if(tCustomer ==null){
                customer = customerService.saveCustomer("百度小程序");
                wxUserService.updateById(wxUser.setUserId(Long.valueOf(customer.getCustomerId())));
            }else {
                log.info("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@数据库已有百度用户：[{}]",tCustomer.getCustomerId());
                redisUtil.set("baidu:customer:"+tCustomer.getCustomerId(),sessionKey, TimeUnit.DAYS.toSeconds(30));
                return APIEntity.success(JwtTokenUtil.createToken("客户",tCustomer.getCustomerId()));
            }
        }
        log.info("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@数据库新增的百度用户：[{}]",customer.getCustomerId());
        redisUtil.set("baidu:customer:"+customer.getCustomerId(),sessionKey,TimeUnit.DAYS.toSeconds(30));
        return APIEntity.success(JwtTokenUtil.createToken("客户",customer.getCustomerId()));
    }

    /**
     * 对密文进行解密
     *
     * @param date 需要解密的密文
     *
     * @return 解密得到的明文
     *
     * @throws Exception 异常错误信息
     */
    @ApiOperation("百度小程序用户信息解密")
    @GetMapping("/getbaidu/userinfo")
    public APIEntity decrypt(@RequestAttribute("JwtUserId") Integer id,String date,String ivStr) throws Exception {
        Object sessionKey = redisUtil.get("baidu:customer:"+id);
        if(sessionKey==null){
            return APIEntity.fail("登陆授权已超时请重新授权");
        }
        TCustomer customer = customerService.getOne(new QueryWrapper<TCustomer>().eq("customer_id",id));//新的账户
        if(customer==null){
            return APIEntity.fail("无法识别用户信息").setStatus(412);
        }
        //获取微信用户信息
        String baiduUserInfoJson= baiduUtils.decrypt(date,sessionKey.toString(),ivStr);
        log.info("百度用户信息：[{}]",baiduUserInfoJson);
        if(baiduUserInfoJson==null){
            log.error("解密用户信息失败，解密返回:[{}]",baiduUserInfoJson);
            return APIEntity.fail("解密用户信息失败");
        }
        JSONObject jsonObject = new JSONObject();
        if(JSONObject.parseObject(baiduUserInfoJson).getString("mobile").equals(customer.getCustomerPhone())){
            jsonObject.put("customerId",customer.getCustomerId());
            jsonObject.put("customerPhone",customer.getCustomerPhone());
            jsonObject.put("token",JwtTokenUtil.createToken("客户",customer.getCustomerId()));
            return APIEntity.success(jsonObject);
        }
        TCustomer tCustomer = customerService.getOne(new QueryWrapper<TCustomer>().eq("customer_phone",JSONObject.parseObject(baiduUserInfoJson).getString("mobile")));//旧的相同手机号账户
        if(tCustomer != null){
            TWxUser wxUser=wxUserService.getOne(new QueryWrapper<TWxUser>().eq("user_id",customer.getCustomerId()).eq("wx_app_name","客户端小程序（百度）"));
            wxUser.setUserId(Long.valueOf(tCustomer.getCustomerId()));
            wxUser.setGmtModified(LocalDateTime.now());
            wxUserService.updateById(wxUser);
            jsonObject.put("customerId",tCustomer.getCustomerId());
            jsonObject.put("customerPhone",tCustomer.getCustomerPhone());
            jsonObject.put("token",JwtTokenUtil.createToken("客户",tCustomer.getCustomerId()));
            customerService.removeById(customer);
        }else {
            customer.setCustomerPhone(JSONObject.parseObject(baiduUserInfoJson).getString("mobile"));
            customer.setUpdateTime(LocalDateTime.now());
            customerService.updateById(customer);
            jsonObject.put("customerId",customer.getCustomerId());
            jsonObject.put("customerPhone",customer.getCustomerPhone());
            jsonObject.put("token",JwtTokenUtil.createToken("客户",customer.getCustomerId()));
        }
        log.info("登陆的账号信息:[{}]",jsonObject);
        return APIEntity.success(jsonObject);
    }


    /**
     * 百度小程序支付异步回调接口
     * 将回调的订单信息放到消息队列里，监听消息队列进行业务处理
     * req
     * @throws Exception
     */
    @ApiOperation("百度小程序支付异步回调接口，前端不需要接入")
    @PostMapping("/pay/notify")
    public JSONObject baiduPayNotify(BaiduPayReq req) throws Exception {
        JSONObject resultObj = new JSONObject();
        JSONObject date = new JSONObject();
        //String str = StreamUtil.readText(request.getInputStream());
        Map<String, Object> sign = JSON.parseObject(JSON.toJSONString(req), new TypeReference<Map<String, Object>>() {});
        sign.put("rsaSign", req.getRsaSign().replace(" ", ""));
        boolean check = RSASign.checkSign(sign, BaiDuConfig.PLATFORM_PUBLIC_KEY);
        log.info("【百度支付验签结果】:{}", check);
        resultObj.put("errno",0);
        resultObj.put("msg","success");
        date.put("isConsumed",2);
        if (!check) {
            date.put("isErrorOrder",1);
            resultObj.put("data",date);
            return resultObj;
        }
        tool.sendMsg(JSONObject.parseObject(JSONObject.toJSONString(req)), BaiDuListener.class);
        date.put("isErrorOrder",2);
        resultObj.put("data",date);
        log.info("【百度支付回调成功】:{}", resultObj);
        return resultObj;
    }

    /**
     * 百度小程序申请退款异步回调接口
     * @param baiduRefundInfo
     * @return
     * @throws Exception
     */
    @ApiOperation("百度小程序申请退款异步回调接口，前端不需要接入")
    @PostMapping("/refund/notify")
    public JSONObject baiduRefundNotify(BaiduRefundInfo baiduRefundInfo) throws Exception {
        JSONObject resultObj = new JSONObject();
        JSONObject date = new JSONObject();
        Map<String, Object> sign = JSON.parseObject(JSON.toJSONString(baiduRefundInfo), new TypeReference<Map<String, Object>>() {});
        sign.put("rsaSign", baiduRefundInfo.getRsaSign().replace(" ", ""));
        boolean check = RSASign.checkSign(sign, BaiDuConfig.PLATFORM_PUBLIC_KEY);
        log.info("【百度退款验签结果】:{}", check);
        resultObj.put("errno",0);
        resultObj.put("msg","success");
        resultObj.put("data",date);
        if (!check) {
            return null;
        }
        //TOrder tOrder = orderService.getOne(new QueryWrapper<TOrder>().eq("order_num",baiduRefundInfo.getTpOrderId()));
        List<TPay> tPays = payService.list(new QueryWrapper<TPay>().eq("pay_num",baiduRefundInfo.getTpOrderId()).eq("pay_status","已支付"));
        for(TPay pay : tPays){
            TOrder tOrder = orderService.getOne(new QueryWrapper<TOrder>().eq("order_num",pay.getMerchantNum()));
            refundService.wxAltRefund(null,null,null,baiduRefundInfo,null,tOrder,pay,null,"业务支付退款");
            TOrderCircu.insertCircu(tOrder);
        }
        log.info("【百度退款回调成功】:{}", resultObj);
        return resultObj;
    }

}
