package com.ruoyi.web.controller.api;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ApiResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.mall.domain.*;
import com.ruoyi.mall.service.*;
import com.ruoyi.web.controller.utils.PayCommonUtil;
import com.ruoyi.web.controller.utils.XiaochengxuPayService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * @ClassName 小程序支付接口
 * @Description 小程序支付接口
 * @Author LCL
 * @Date 2023/10/18
 * @Version 1.0
 **/
// @RequestMapping("/api/pay")
// @Controller
@RestController
@RequestMapping("/api/pay")
public class ApiPayController {

    @Resource
    private IMallMemberUserService memberUserService;

    @Resource
    private IVipGuideService vipGuideService;

    @Resource
    private IMallPayLogService mallPayLogService;

    @Resource
    XiaochengxuPayService xiaochengxuPayService;

    @Resource
    private IMemberReportIntelligenceService memberReportIntelligenceService;
    @Resource
    private IMallConfigService mallConfigService;

    @Resource
    private IUserCouponService userCouponService;

    /**
     * 微信小程序支付接口
     *
     * @param params
     * @param req
     * @return
     */
    @RequestMapping("/xcxPay")
    @ResponseBody
    public AjaxResult xcxPay(@RequestBody Map<String, Object> params, HttpServletRequest req) {
        try {
            if (!params.containsKey("guideId") || !params.containsKey("userId")) {
                return AjaxResult.error("缺少参数");
            }
            String guideId = params.get("guideId").toString();
            String userId = params.get("userId").toString();
            MallMemberUser userDO = memberUserService.selectMallMemberUserById(Long.parseLong(userId));
            if (userDO == null) {
                return AjaxResult.error(103, "用户异常");
            }

            VipGuide vipGuide = vipGuideService.selectVipGuideByGuideId(Long.parseLong(guideId));

            // 生成支付记录
            MallPayLog payLog = new MallPayLog();

            BigDecimal payment = vipGuide.getDiscountMoney();

            if (params.containsKey("userPrice") && StringUtils.isNotBlank(params.get("userPrice").toString())) {
                BigDecimal userPrice = new BigDecimal(params.get("userPrice").toString());
                if (userPrice.compareTo(new BigDecimal(0)) > 0){
                    payment = userPrice;
                }
            }

            if (params.containsKey("cuId") && StringUtils.isNotBlank(params.get("cuId").toString())) {
                String cuId = params.get("cuId").toString();
                // 使用优惠券
                UserCoupon userCoupon = userCouponService.selectUserCouponByCuId(Long.parseLong(cuId));
                if (userCoupon == null || !"1".equals(userCoupon.getStatus())) {
                    return AjaxResult.error(103, "优惠券异常");
                }
                BigDecimal couponMoney = new BigDecimal(userCoupon.getCouponMoney());
                payment = vipGuide.getDiscountMoney().subtract(couponMoney);

                payLog.setResId(cuId);// 用户优惠券ID
            }

            SortedMap<String, String> signMap = new TreeMap<>();

            String outTradeNo = orderIdGenerator();


            payLog.setUserId(Long.parseLong(userId));
            payLog.setGuideId(Long.parseLong(guideId));
            payLog.setOutTradeNo(outTradeNo);
            payLog.setStatus("0");
            payLog.setType("1");
            payLog.setPrice(payment);
            mallPayLogService.insertMallPayLog(payLog);

            if (payment.compareTo(new BigDecimal("0")) > 0) {

                signMap.put("body", "艺智果会员"); //商品描述  必
                signMap.put("attach", "艺智果会员"); //商品描述  必
                signMap.put("openid", userDO.getOpenid()); //商品详情  非
                signMap.put("out_trade_no", outTradeNo); //商户订单号  必
                float sessionmoney = Float.parseFloat(payment.toString());
                String finalmoney = String.format("%.2f", sessionmoney);
                finalmoney = finalmoney.replace(".", "");
                String newStr = finalmoney.replaceFirst("^0*", "");
                signMap.put("total_fee", newStr); //总金额  必
                signMap.put("spbill_create_ip", StringUtils.getRemoteAddr(req)); //终端ip  用户端ip  必

                Map<String, Object> relMap = xiaochengxuPayService.getOrderSignature(signMap);
                return AjaxResult.success().put("data", relMap);
            } else {
                // 修改支付记录及用户信息
                mallPayLogService.updateMallPayLogAndMember(outTradeNo);
                // 修改用户优惠券状态
                mallPayLogService.updateMemberCouponStatus(outTradeNo);
                return AjaxResult.error(101, "支付成功");
            }

        } catch (Exception e) {
            return AjaxResult.error("返回调起微信支付参数失败!");
        }
    }

    /**
     * 小程序支付回调
     *
     * @param req
     * @param res
     * @return
     */
    @ResponseBody
    @RequestMapping("/xcxPayNotify")
    public Object xcxPayNotify(HttpServletRequest req, HttpServletResponse res) {
        try {
            InputStream inStream = req.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            System.out.println("~~~~~~~~~~~~~~~~付款成功666~~~~~~~~~");
            outSteam.close();
            inStream.close();
            String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
            Map<Object, Object> mapFromXml = PayCommonUtil.doXMLParse(result);
//            log.error("mapFromXml::" +mapFromXml.toString());
            SortedMap<String, String> sortedMap = new TreeMap();
            if (mapFromXml.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
                String outTradeNo = mapFromXml.get("out_trade_no").toString();
                MallPayLog payLog = mallPayLogService.selectMallPayLogByOutTradeNo(outTradeNo);
                if (payLog == null) {
                    return "fail";
                }
                //  验签成功后
                //获取支付订单类型
                String type = payLog.getType();
                if(StringUtils.isNotBlank(type) && type.equals("1")){
                    mallPayLogService.updateMallPayLogAndMember(outTradeNo);
                }else if(StringUtils.isNotBlank(type) && type.equals("2")){
                    mallPayLogService.updateMallPayLogAndReport(outTradeNo);
                }

                // 修改用户优惠券状态
                mallPayLogService.updateMemberCouponStatus(outTradeNo);


                sortedMap.put("return_code", "SUCCESS");
                sortedMap.put("return_msg", "OK");
                BufferedOutputStream out = new BufferedOutputStream(
                        res.getOutputStream());
                out.write(parseXML(sortedMap).getBytes());
                out.flush();
                out.close();


            } else {
                sortedMap.put("return_code", "FAIL");
                sortedMap.put("return_msg", "签名失败");
                BufferedOutputStream out = new BufferedOutputStream(
                        res.getOutputStream());
                out.write(parseXML(sortedMap).getBytes());
                out.flush();
                out.close();
            }
            return "success";
        } catch (Exception e) {
            return "failure";
        }
    }

    //输出XML
    public String parseXML(Map map) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>\n");
        Set es = map.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"appkey".equals(k)) {

                sb.append("<" + k + "><![CDATA[" + v + "]]></" + k + ">\n");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public String orderIdGenerator() {
        String time = DateUtils.dateTimeNow();
        String randomString = RandomStringUtils.randomNumeric(8);
        return time + randomString;
    }

    /**
     * test
     *
     * @return
     */
    @GetMapping("/test")
    public AjaxResult test(String outTradeNo) {
        try {
            mallPayLogService.updateMallPayLogAndMember(outTradeNo);
            return AjaxResult.success();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("test异常");
        }
    }

///////////////////////////////////支付————志愿报告审核
    /**
     * 志愿报告审核-支付接口
     *
     * @param params
     * @param req
     * @return
     */
    @RequestMapping("/xcxPayForReportChecka")
    @ResponseBody
    public AjaxResult xcxPayForReportCheck(@RequestBody Map<String, Object> params, HttpServletRequest req) {
        try {
            if (!params.containsKey("reportId") || !params.containsKey("userId")) {
                return AjaxResult.error("缺少参数");
            }
            String reportId = params.get("reportId").toString();
            String userId = params.get("userId").toString();
            MallMemberUser userDO = memberUserService.selectMallMemberUserById(Long.parseLong(userId));
            if (userDO == null) {
                return AjaxResult.error(103, "用户异常");
            }

            //查询报告实例
            MemberReportIntelligence memberReportIntelligence = memberReportIntelligenceService.selectMemberReportIntelligenceByReportId(Long.parseLong(reportId));
            MallConfig checkRemarkMoney = mallConfigService.selectMallConfigByMarK("check_remark_money");
            String checkMoneyS =  checkRemarkMoney.getContent();

            SortedMap<String, String> signMap = new TreeMap<>();

            String outTradeNo = orderIdGenerator();

            signMap.put("body", "艺智果-志愿报告审核"); //商品描述  必
            signMap.put("attach", "艺智果-志愿报告审核"); //商品描述  必
            signMap.put("openid", userDO.getOpenid()); //商品详情  非
            signMap.put("out_trade_no", outTradeNo); //商户订单号  必
            float sessionmoney = Float.parseFloat(checkRemarkMoney.getContent());
            String finalmoney = String.format("%.2f", sessionmoney);
            finalmoney = finalmoney.replace(".", "");
            String newStr = finalmoney.replaceFirst("^0*", "");
            signMap.put("total_fee", newStr); //总金额  必
            signMap.put("spbill_create_ip", StringUtils.getRemoteAddr(req)); //终端ip  用户端ip  必

            Map<String, Object> relMap = xiaochengxuPayService.getOrderSignature(signMap);

            // 生成支付记录
            MallPayLog payLog = new MallPayLog();
            payLog.setUserId(Long.parseLong(userId));
            payLog.setGuideId(Long.parseLong(reportId));
            payLog.setOutTradeNo(signMap.get("out_trade_no"));
            payLog.setStatus("0");
            //支付类型 0-订单 1-会员 2-志愿报告审核支付
            payLog.setType("2");
            payLog.setPrice(new BigDecimal(checkRemarkMoney.getContent()));
            mallPayLogService.insertMallPayLog(payLog);

            return AjaxResult.success().put("data", relMap);

        } catch (Exception e) {
            return AjaxResult.error("返回调起微信支付参数失败!");
        }
    }





}
