package com.app.controller.api;

import com.app.annotation.platform.OperationLog;
import com.app.entity.guardian.Guardian;
import com.app.service.guardian.GuardianService;
import com.app.service.order.OpenCourseOrderService;
import com.app.util.DateUtil;
import com.github.wxpay.sdk.WXPayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 微信支付接口签名校验工具
 * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1
 */
@Api(description = "支付")
@Slf4j
@Validated
@RestController("ApiPayController")
@RequestMapping("/api/pay")
public class PayController {

    @Autowired
    private GuardianService guardianService;

    @Autowired
    private OpenCourseOrderService openCourseOrderService;

    /**
     * 功能描述：微信支付 - 回调通知
     * 官方文档：
     * 支付结果通知：
     * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7&index=8
     * <p>
     * 回调通知注意事项：
     * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=23_8&index=5
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @OperationLog("更新 - 微信支付回调")
    @ApiOperation(value = "微信支付[回调]")
    @PostMapping("/wx/notify")
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("UTF-8");

        /* 获取响应XML数据 */
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        String notityXml = sb.toString();
        log.info("微信支付[回调] 参数：[{}]", notityXml);

        Map<String, String> notityParamMap = WXPayUtil.xmlToMap(notityXml);
        if (!"SUCCESS".equalsIgnoreCase(notityParamMap.get("return_code"))) {
            log.error("微信支付[回调] 错误：[{}]", notityParamMap.get("return_msg"));
        }

        String orderId = notityParamMap.get("out_trade_no"); // 获取商户订单号
        Optional<Guardian> optional = guardianService.findByOpenId(notityParamMap.get("openid"));
        if (optional.isPresent()) {
            Guardian _guardian = optional.get();

            String transactionId = notityParamMap.get("transaction_id"); // 微信支付订单号
            Double paidPrice = BigDecimal.valueOf(Integer.parseInt(notityParamMap.get("total_fee"))).divide(new BigDecimal(100)).doubleValue(); // 订单金额(分转元)
            Date timeEnd = DateUtil.format(notityParamMap.get("time_end"), DateUtil.yyyyMMddHHmmss); // 支付完成时间
            openCourseOrderService.payToEnd(orderId, _guardian.getId(), transactionId, paidPrice, timeEnd);

            /* 构造 微信支付[回调] 正确响应内容 */
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/xml;charset=utf-8;");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setStatus(HttpStatus.OK.value());
            response.getWriter().write(WXPayUtil.mapToXml(new HashMap<String, String>(){{
                put("return_code", "SUCCESS");
                put("return_msg", "OK");
            }}));
        }
    }

    // todo 还缺一个退款通知的金额统计... https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_16&index=10

}
