package com.supplier.controller;

import com.supplier.model.BuyOfferNum;
import com.supplier.model.SupplierRelease;
import com.supplier.model.WxPay;
import com.supplier.service.SupplierReleaseService;
import com.supplier.service.WxPayService;
import com.supplier.util.SnowflakeUtil;
import com.supplier.util.WXPayUtil;
import com.supplier.vx.pay.HttpUtil;
import com.supplier.util.PayToolUtil;
import com.supplier.vx.pay.WxPayUtils;
import org.jdom2.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * app支付
 */
@RestController
@RequestMapping("appPay")
public class WxPayAppController extends WxPayUtils {

    private SnowflakeUtil snowflakeUtil = new SnowflakeUtil(1, 1, 1);

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private SupplierReleaseService supplierReleaseService;

    /**
     * app预支付
     * @param price 金额
     * @return 返回结果
     */
    @RequestMapping("wxPayApp")
    @ResponseBody
    public Map<String, Object> wxPayApp(String price, String attach){
        Map<String, Object> map = new HashMap<>();
        try{
            if(price.equals("0")){
                map.put("errMsg", "付款金额错误");
                map.put("msg", "500");
                return map;
            }
            //拼接参数
            WXPayUtil wxPayUtil = new WXPayUtil(); //微信工具类
            PayToolUtil payToolUtil = new PayToolUtil();//数据转换工具类
            String outTradeNo = wxPayUtil.getOrderNo();
            String nonce_str = wxPayUtil.generateNonceStr();
            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            //获取订单金额
            SupplierRelease supplierRelease = new SupplierRelease().setUuid(attach);
            List<SupplierRelease> list = supplierReleaseService.getSupplierRelease(supplierRelease);

            packageParams.put("appid", APPID);//app_id---需要申请
            packageParams.put("attach", attach);//报价单编号
            packageParams.put("body", "途丫-" + outTradeNo);//商品参数信息
            packageParams.put("fee_type", "CNY");//货币类型
            packageParams.put("mch_id", MCHID);//微信商户账号--需要申请
            packageParams.put("nonce_str", nonce_str);//32位不重复的编号
            packageParams.put("notify_url", NOTIFY_URL);//回调页面--这个是回调接口
            packageParams.put("out_trade_no", outTradeNo);//订单编号
            packageParams.put("spbill_create_ip", CREATE_IP);//金额
            packageParams.put("total_fee", wxPayUtil.getMoney(list.get(0).getPriceAll()));//金额
            packageParams.put("trade_type", "APP");//支付类型
            // 签名
            String sign = payToolUtil.createSign("UTF-8", packageParams, KEY);
            packageParams.put("sign", sign);
            // 将请求参数转换为xml格式的string
            String requestXML = payToolUtil.getRequestXml(packageParams);
            // 调用微信支付统一下单接口
            String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
            //xml返回结果转换
            Map<String, String> mapVal = wxPayUtil.xmlToMap(resXml);
            if(null == mapVal.get("prepay_id")){
                throw new Exception("获取预支付id失败");
            }

            Map<String, Object> mapVal1 = new HashMap<>();
            String time = String.valueOf(wxPayUtil.getCurrentTimestamp());
            mapVal1.put("outTradeNo", outTradeNo);//自生成订单号
            mapVal1.put("prepayId", mapVal.get("prepay_id"));//微信订单号
            mapVal1.put("nonceStr", nonce_str); //不重复编号
            mapVal1.put("time", time); //不重复编号
            mapVal1.put("sign", wxPayUtil.singGenerate(packageParams, mapVal.get("prepay_id"), KEY, time, nonce_str)); //签名

            map.put("msg", "200");
            map.put("data", mapVal1);

            WxPay wxPay1 = wxPayService.getRefundVal(attach);//获取付该报价单付款的信息
//            if(null != wxPay1){
//                throw new Exception("请勿重复支付");
//            }

            //生成uuid
            String uuid = UUID.randomUUID().toString().replace("-", "");
            WxPay wxPay = new WxPay()
                    .setUuid(uuid)
                    .setMchId(MCHID)
                    .setReleaseUuid(attach)
                    .setCodeUrl((String) map.get("code_url"))
                    .setOutTradeNo(outTradeNo)
                    .setTotalFee(price)
                    .setBody("途丫-" + outTradeNo);
            wxPayService.pay(wxPay);

        }catch (Exception e){
            e.printStackTrace();
            map.put("msg", "500");
            map.put("errMsg", "服务器请求异常，请稍后再试");
        }
        return map;
    }


    /**
     * app支付回调
     * @param request 参数
     * @param response 参数
     * @return 返回结果
     */
    @RequestMapping("appNotify")
    @ResponseBody
    public String appNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //读取参数
        InputStream inputStream ;
        StringBuffer sb = null;
        try {
            sb = new StringBuffer();
            inputStream = request.getInputStream();
            String s ;
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((s = in.readLine()) != null){
                sb.append(s);
            }
            in.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //解析xml成map
        Map<String, String> mapVal = new HashMap<String, String>();
        WXPayUtil wxPayUtil = new WXPayUtil(); //微信工具类
        try {
            mapVal = wxPayUtil.xmlToMap(sb.toString());
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //过滤空 设置 TreeMap
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
        Iterator it = mapVal.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = mapVal.get(parameter);
            String v = "";
            if(null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }
        //判断签名是否正确
        if(PayToolUtil.isTenpaySign("UTF-8", packageParams, KEY)) {
            //业务处理
            String resXml = "";
            if("SUCCESS".equals((String)packageParams.get("result_code"))){
                //生成uuid
                String uuid = UUID.randomUUID().toString().replace("-", "");
                WxPay wxPay = new WxPay()
                        .setUuid(uuid)
                        .setReleaseUuid((String)packageParams.get("attach"))
                        .setFeeType((String)packageParams.get("fee_type"))
                        .setMchId((String)packageParams.get("mch_id"))
                        .setNonceStr((String)packageParams.get("nonce_str"))
                        .setOutTradeNo((String)packageParams.get("out_trade_no"))
                        .setTotalFee((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "")
                        .setTradeType((String)packageParams.get("trade_type"))
                        .setPrepayId((String)packageParams.get("transaction_id"))
                        .setOpenId((String)packageParams.get("openid"))
                        .setTimeEnd((String)packageParams.get("time_end"));
                //如果自定义参数是gysTopUp则代表的是供应商充值余额
                if(((String) packageParams.get("attach")).indexOf("gysTopUp") != -1){
                    WxPay buySupplier = new WxPay()
                            .setCode(((String) packageParams.get("attach")).split(",")[2])
                            .setUuid(((String) packageParams.get("attach")).split(",")[1])
                            .setTotalFee((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "");
                    wxPayService.updateBuySupplier(buySupplier); //充值
                } else if(((String) packageParams.get("attach")).indexOf("gysOfferNum") != -1){ //报价单次数购买
                    BuyOfferNum buyOfferNum = new BuyOfferNum()
                            .setCode(((String) packageParams.get("attach")).split(",")[2])
                            .setUuid(((String) packageParams.get("attach")).split(",")[1])
                            .setPayAmount((float)Integer.parseInt((String)packageParams.get("total_fee")) / 100 + "")
                            .setOfferNum(((String) packageParams.get("attach")).split(",")[3]);
                    wxPayService.updateBuyOfferNum(buyOfferNum);//购买次数
                } else { //报价单购买
                    wxPayService.payUpdate(wxPay);
                    //修改报价单信息
                    SupplierRelease supplierRelease = new SupplierRelease().setUuid((String)packageParams.get("attach"));
                    List<SupplierRelease> list = supplierReleaseService.getSupplierRelease(supplierRelease);

                    List<SupplierRelease> list1 = supplierReleaseService.getSupplierReleaseType(list.get(0).getDemandUuid());
                    for(SupplierRelease supplierRelease1 : list1){
                        //修改定制单状态判断是否是当前报价单的供应商
                        SupplierRelease supplierRelease2 = new SupplierRelease()
                                .setCode(supplierRelease1.getCode())
                                .setDemandUuid(supplierRelease1.getDemandUuid());
                        if(supplierRelease1.getCode().equals(list.get(0).getCode())){
                            supplierRelease2.setOrderType("2");
                            supplierReleaseService.updatePrivateType(supplierRelease2);
                        } else {
                            supplierRelease2.setOrderType("9");
                            supplierReleaseService.updatePrivateType(supplierRelease2);//修改状态
                            supplierReleaseService.updateSupplierOffer(supplierRelease2);//返回报价单次数
                        }
                    }
                }
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return ("fail");
            }
            try {
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        } else {
            throw new Exception("签名验证失败");
        }
        return ("success");
    }
}
