package com.miaxis.wx.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.miaxis.common.config.WxpayConfig;
import com.miaxis.common.core.domain.entity.UserInfo;
import com.miaxis.common.enums.OrderStatusEnum;
import com.miaxis.common.exception.CustomException;
import com.miaxis.user.service.IUserInfoService;
import com.miaxis.wx.domain.RefundRecord;
import com.miaxis.wx.domain.WxOrder;
import com.miaxis.wx.dto.WxNotifyReturnDTO;
import com.miaxis.wx.mapper.RefundRecordMapper;
import com.miaxis.wx.service.IRefundRecordService;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 微信退款记录Service业务层处理
 *
 * @author miaxis
 * @date 2021-05-18
 */
@Service
public class RefundRecordServiceImpl extends ServiceImpl<RefundRecordMapper, RefundRecord> implements IRefundRecordService {
    @Resource
    private RefundRecordMapper refundRecordMapper;

    @Autowired
    private HttpClient httpClient;


    @Autowired
    private WxpayConfig wxpayConfig;

    @Autowired
    private IUserInfoService userInfoService;
    /**
     * 查询微信退款记录列表
     *
     * @param refundRecord 微信退款记录
     * @return 微信退款记录
     */
    @Override
    public List<RefundRecord> selectRefundRecordList(RefundRecord refundRecord){
        return refundRecordMapper.selectRefundRecordList(refundRecord);
    }

    @Override
    public WxNotifyReturnDTO refund(WxOrder wxOrder, String refundCode,String failCause) throws Exception{
        if (failCause.length()>80){
            failCause = "购买失败，详情请在小程序查看";
        }
        HttpPost httpPost = new HttpPost(wxpayConfig.getV3urlRefund());
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("out_trade_no", wxOrder.getOutTradeNo())
                .put("out_refund_no", refundCode)
                .put("reason", failCause)
                .put("notify_url",wxpayConfig.getNotifyUrlRefund());
        rootNode.putObject("amount")
                .put("refund", wxOrder.getTotal())
                .put("total", wxOrder.getTotal())
                .put("currency", wxOrder.getCurrency());

//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//        objectMapper.writeValue(bos, rootNode);
        httpPost.setEntity(new StringEntity(rootNode.toString(), "utf-8"));
        HttpResponse response = httpClient.execute(httpPost);
        // 返回数据：
        String bodyAsString = EntityUtils.toString(response.getEntity());
        if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
            wxOrder.setOutRefundNo(refundCode);
            //  保存退款数据到数据库
            RefundRecord refundRecord = new RefundRecord();
            JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
            refundRecord.setRefundId(jsonObject.getString("refund_id"));
            refundRecord.setOutRefundNo(jsonObject.getString("out_refund_no"));
            refundRecord.setTransactionId(jsonObject.getString("transaction_id"));
            refundRecord.setOutTradeNo(jsonObject.getString("out_trade_no"));
            refundRecord.setChannel(jsonObject.getString("channel"));
            refundRecord.setUserReceivedAccount(jsonObject.getString("user_received_account"));
            if (jsonObject.getString("success_time")!=null){
                refundRecord.setSuccessTime(new DateTime(jsonObject.getString("success_time")).toDate());
                wxOrder.setTradeState("");
            }
            refundRecord.setCreateTime(new DateTime(jsonObject.getString("create_time")).toDate());
            refundRecord.setStatus(jsonObject.getString("status"));
            refundRecord.setFundsAccount(jsonObject.getString("funds_account"));
            JSONObject amount = jsonObject.getJSONObject("amount");
            refundRecord.setTotal(amount.getInteger("total"));
            refundRecord.setRefund(amount.getInteger("refund"));
            refundRecord.setPayerTotal(amount.getInteger("payer_total"));
            refundRecord.setPayerRefund(amount.getInteger("payer_refund"));
            refundRecord.setSettlementRefund(amount.getInteger("settlement_refund"));
            refundRecord.setSettlementTotal(amount.getInteger("settlement_total"));
            refundRecord.setDiscountRefund(amount.getInteger("discount_refund"));
            refundRecord.setCurrency(amount.getString("currency"));
            this.save(refundRecord);

            //退款完成 解除会员vip身份
            UserInfo userInfo = userInfoService.getOne(new QueryWrapper<UserInfo>().eq("app_openid", wxOrder.getAppOpenid()));
            userInfo.setIsVip(0);
            userInfoService.updateById(userInfo);


            //改变订单状态




            WxNotifyReturnDTO wxNotifyReturnDTO = new WxNotifyReturnDTO();
            wxNotifyReturnDTO.setCode("SUCCESS");
            wxNotifyReturnDTO.setMessage("成功");
            return wxNotifyReturnDTO;
        }else{
            throw new CustomException(bodyAsString);
        }

    }

    @Override
    public RefundRecord getByRefundId(String refundId) {
        return refundRecordMapper.getByRefundId(refundId);
    }
}
