package com.icloud.server.payutils.notify;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConfig;
import com.alipay.api.internal.util.AlipaySignature;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.icloud.server.payutils.PayClient;
import com.icloud.server.payutils.PayClientFactory;
import com.icloud.server.payutils.ali.util.AlipayNotify;
import com.icloud.server.payutils.dto.PayNotifyDataDTO;
import com.icloud.server.payutils.dto.PayOrderDO;
import com.icloud.server.scala.goods.Goods;
import com.icloud.server.scala.goods.GoodsRepository;
import com.icloud.server.scala.goods.Goodspay;
import com.icloud.server.scala.goods.GoodspayRepository;
import com.icloud.server.scala.pay.Alipay1;
import com.icloud.server.scala.pay.Alipay1Repository;
import com.icloud.server.scala.paynotify.PayNotifyEntity;
import com.icloud.server.scala.paynotify.PayNotifyLogEntity;
import com.icloud.server.scala.paynotify.PayNotifyLogRepository;
import com.icloud.server.scala.paynotify.PayNotifyRepository;
import com.icloud.server.scala.payorder.PayOrderRepository;
import com.icloud.server.utils.JsonUtils;
import com.icloud.server.utils.log.Logs;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.*;

import com.alipay.api.internal.util.AlipaySignature;
import springfox.documentation.annotations.ApiIgnore;

import static com.icloud.server.web.err.enums.ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND;

/**
 * 微信
 *
 * @Author : yang
 * @Date : 2022-07-26 01:09
 * @Version : 2.1.2
 */

@Api(tags = "支付宝回传")
@ApiIgnore
@RestController
@RequestMapping("/occloud/pay/aliorder")
@Validated
@Slf4j
@AllArgsConstructor
public class AliPayNotify {

    @Resource
    private PayClientFactory payClientFactory;
    @Resource
    private PayNotifyRepository pnr;
    @Resource
    private Alipay1Repository ar;
    @Resource
    private PayOrderRepository por;
    @Resource
    private PayNotifyLogRepository pnlr;
    @Resource
    private GoodsRepository gr;
    @Resource
    private GoodspayRepository gpr;


    static Logger logger = LoggerFactory.getLogger("alirepay");



    @PostMapping(value = "/alinotify/{channelId}")
    @ApiOperation("渠道统一的支付成功,或退款成功 通知url")
    public String aa(@PathVariable("channelId") Long channelId, HttpServletRequest request, HttpServletResponse response){




        System.out.println("=======支付宝回调:alinotify========");
        System.out.println("channelId:" + channelId);
        System.out.println("=======request:"+request);
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        System.out.println("params:"+ JsonUtils.toJsonString(params));
        HashMap<String, String> map = new HashMap<>();
        for(Object str:requestParams.keySet()){
            String parameter = request.getParameter(str.toString());
            map.put(str.toString(),parameter);
            System.out.println("key======"+str+":"+parameter);
        }
        String req = JsonUtils.toJsonString(map);
        System.out.println("map:"+req);
        //out_trade_no
        String out_trade_no = request.getParameter("out_trade_no");
        String total_amount = request.getParameter("total_amount");
        System.out.println("out_trade_no:"+out_trade_no);
        PayOrderDO byMerchantorderid = por.findByMerchantorderid(out_trade_no);
        Optional<Alipay1> alipay1 = ar.findById(byMerchantorderid.getAppid());
        String alipaypublickey = alipay1.get().getAlipaypublickey();
        System.out.println("====alipaypublickey===:"+alipaypublickey);




        try {
//            boolean verify_result = AlipaySignature.rsaCheckV1(params,alipaypublickey,"UTF-8","RSA2");
            Boolean verify_result = flag2(request, alipaypublickey);
            System.out.println("verify_result:"+verify_result);
            verify_result=true;
            if(verify_result){
                System.out.println("订单支付成功");

                List<PayNotifyEntity> pnes = pnr.findByMerchantorderidAndStatus(out_trade_no,0);
                if(!pnes.isEmpty()){
                    PayNotifyLogEntity paynotifylogentity = new PayNotifyLogEntity().toEntity(out_trade_no, req, "ali", "ali", byMerchantorderid.getAppid().toString());
                    //mysql 记录
                    pnlr.save(paynotifylogentity);
                    //log 日志----输出
                    new Logs(logger).toLog( req);
                    PayNotifyEntity entity = pnes.get(0);
                    String merchantorderid = entity.getMerchantorderid();
                    entity.setStatus(1);
                    pnr.save(entity);
                    PayOrderDO por1 = por.findByMerchantorderid(merchantorderid);
                    por1.setStatus(1);
                    //mysql --修改订单状态
                    por.save(por1);

                    try {
                        Long goodspayid = por1.getGoodspayid();
                        Optional<Goodspay> goodspay = gpr.findById(goodspayid);
                        Goodspay goodspay1 = goodspay.get();
                        Goods goods = gr.findByGoodsid(goodspay1.getGoodsid());
                        long sellamount = goods.getSellamount();
                        long sellcount = goods.getSellcount();
                        sellamount+=strtoLong(total_amount);
                        sellcount+=1;
                        goods.setSellamount(sellamount);
                        goods.setSellcount(sellcount);
                        gr.save(goods);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }


        return "success";
    }

    @GetMapping("/t")
    public void test(HttpServletRequest request, HttpServletResponse response){
        Map requestParams = request.getParameterMap();



    }

    @PostMapping(value = "/alinotify3/{channelId}")
    @ApiOperation("渠道统一的支付成功,或退款成功 通知url")
    public String notifyChannelPay(@PathVariable("channelId") Long channelId,
                                   @RequestParam Map<String, String> params,
                                   @RequestBody String originData) throws Exception {

        System.out.println("channelId:"+channelId);
        System.out.println("originData:"+originData);
        String out_trade_no = params.get("out_trade_no");
        PayOrderDO byMerchantorderid = por.findByMerchantorderid(out_trade_no);
        Optional<Alipay1> alipay1 = ar.findById(byMerchantorderid.getAppid());
        String alipaypublickey = alipay1.get().getAlipaypublickey();
        System.out.println("====alipaypublickey===:"+alipaypublickey);
        // 校验通知数据是否合法
        PayNotifyDataDTO notifyData = PayNotifyDataDTO.builder().params(params).body(originData).build();
        String req = JsonUtils.toJsonString(notifyData.getParams());
        System.out.println("req:"+req);
        boolean verify_result = AlipaySignature.rsaCheckV1(notifyData.getParams(),alipaypublickey,StandardCharsets.UTF_8.name(),"RSA2");

        System.out.println("=====支付成功=====:"+verify_result);
        // 如果是退款，则发起退款通知

        return "success";
    }
    public Boolean flag(HttpServletRequest request,String key) throws AlipayApiException {
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
//切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean flag = AlipaySignature.rsaCheckV1(params, key, "utf-8","RSA2");
        return flag;
    }
    public Boolean flag2(HttpServletRequest request,String key) throws AlipayApiException {
//获取支付宝POST过来反馈信息
        Map< String , String > params = new HashMap < String , String > ();
        Map requestParams = request.getParameterMap();
        for(Iterator iter = requestParams.keySet().iterator();iter.hasNext();){
            String name = (String)iter.next();
            String[] values = (String [])requestParams.get(name);
            String valueStr = "";
            for(int i = 0;i < values.length;i ++ ){
                valueStr =  (i==values.length-1)?valueStr + values [i]:valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put (name,valueStr);
        }
        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean flag = AlipaySignature.rsaCheckV1 (params,key, "utf-8","RSA2");
        System.out.println("======阿里的RSA2校验:"+flag);
//        boolean verify_result = false;
//        try {
//            verify_result = AlipayNotify.verify(requestParams,params.get("sign"));
//            System.out.println("======自己的校验:"+verify_result);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//
////            new AlipayConfig().getCharset();
////            verify_result = AlipaySignature.rsaCheckV1(hm,pk2, "utf-8","RSA2");
//        System.out.println(verify_result);

        return flag;
    }

    public Long strtoLong(String str){
        String s = str.replace(".", "");
        return Long.parseLong(s);
    }


}
