package cn.newfeifan.mall.module.pay.service.fuyouorder;

import cn.newfeifan.mall.framework.common.exception.ErrorCode;
import cn.newfeifan.mall.module.pay.dal.dataobject.order.PayOrderDO;
import cn.newfeifan.mall.module.pay.dal.dataobject.order.PayOrderExtensionDO;
import cn.newfeifan.mall.module.pay.dal.mysql.order.PayOrderExtensionMapper;
import cn.newfeifan.mall.module.pay.enums.order.PayOrderStatusEnum;
import cn.newfeifan.mall.module.pay.fuiou.reqdata.CommonQueryDataReq;
import cn.newfeifan.mall.module.pay.fuiou.respVO.FuYouQueryPayOrderResponseVO;
import cn.newfeifan.mall.module.pay.fuiou.util.DateUtils;
import cn.newfeifan.mall.module.pay.fuiou.util.FuiouHttpPoster;
import cn.newfeifan.mall.module.pay.fuiou.util.MD5;
import cn.newfeifan.mall.module.pay.service.order.PayOrderService;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.newfeifan.mall.module.pay.enums.DictTypeConstants.*;

@Slf4j
@Service
public class FuYouPayOrderServiceImpl implements FuYouPayOrderService {

    @Resource
    @Lazy
    private PayOrderService payOrderService;

    @Resource
    private PayOrderExtensionMapper orderExtensionMapper;


    @Override
    public PayOrderDO getPayOrderByStatus(PayOrderExtensionDO payOrderExtensionDO, PayOrderDO payOrder) {

        // 用一个新的对象接收，避免修改原对象
        PayOrderDO payOrderDO = payOrderService.getOrder(payOrder.getId());

        FuiouHttpPoster http = new FuiouHttpPoster();
        http.setCharset("utf-8");
        http.setUrl("https://aipay.fuioupay.com/aggregatePay/commonQuery");
        CommonQueryDataReq req = new CommonQueryDataReq();
        req.setVersion("1.0");
        req.setMchnt_cd(mchnt_cd);
        req.setRandom_str(DateUtils.getCurrentDate("yyyyMMddHHmmss")
                + "568974");
        req.setOrder_type(payOrderExtensionDO.getChannelCode());
        req.setMchnt_order_no(payOrderDO.getPayOrderNo());
        req.setTerm_id(term_id);
        String data = MD5.MD5Encode(req.getMchnt_cd() + "|" + req.getOrder_type() + "|" +
                req.getMchnt_order_no() + "|" + req.getTerm_id() + "|" + req.getRandom_str() + "|" +
                req.getVersion() + "|" + privateKey);
        req.setSign(data);

        String res;
        try {
            res = http.newPost(JSON.toJSONString(req));

            ObjectMapper mapper = new ObjectMapper();
            FuYouQueryPayOrderResponseVO resp = mapper.readValue(res, FuYouQueryPayOrderResponseVO.class);

            // 当响应结果为000000且交易状态为SUCCESS时才是支付成功
            if (resp.getResult_code().equals(resultCode) && resp.getTrans_stat().equals(transStatus)) {
                // 修改订单扩展信息
                payOrderExtensionDO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());

                // 修改订单信息
                payOrderDO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
                payOrderDO.setExtensionId(payOrderExtensionDO.getId());
                payOrderDO.setNo(payOrderExtensionDO.getNo());
                payOrderDO.setChannelOrderNo(resp.getTransaction_id());
                payOrderDO.setChannelUserId(resp.getBuyer_id());
                payOrderDO.setChannelId(payOrderExtensionDO.getChannelId());
                payOrderDO.setChannelCode(payOrderExtensionDO.getChannelCode());

                payOrderService.updatePayOrder(payOrderDO);
            } else {
                // 否则支付失败, 记录错误信息
                payOrderExtensionDO.setChannelErrorCode(resp.getResult_code());
                payOrderExtensionDO.setChannelErrorMsg(resp.getResult_msg());

            }
            payOrderExtensionDO.setChannelNotifyData(res);
            orderExtensionMapper.updateById(payOrderExtensionDO);

        } catch (Exception e) {
            ErrorCode ERROR = new ErrorCode(1_007_901_006, "查询支付订单失败");
            throw exception(ERROR);
        }

        return payOrderDO;
    }

}
