package com.api.controller.v1;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.HttpsUtils;
import com.hfkj.entity.BsTradeOrder;
import com.hfkj.openapi.v1.model.response.ResponseQueryTradeModel;
import com.hfkj.openapi.v1.service.OpenApiTradeOrderService;
import com.hfkj.openapi.v1.utils.SignatureUtil;
import com.hfkj.service.BsMerKeyService;
import com.hfkj.service.BsTradeOrderService;
import com.hfkj.sysenum.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Controller
@Api(value = "交易订单")
@RequestMapping(value = "/v1/payNotify")
public class NotifyController {

    private static Logger log = LoggerFactory.getLogger(NotifyController.class);

    @Resource
    private BsTradeOrderService tradeOrderService;

    @Resource
    private OpenApiTradeOrderService openApiTradeOrderService;

    @Resource
    private BsMerKeyService merKeyService;

    @RequestMapping(value="/lakala",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "拉卡拉交易通知")
    public void lakala(@RequestBody String reqBody, HttpServletResponse response) {
        try {
            log.info("========= Start 拉卡拉交易通知 Start ===========");
            log.info("平台接收拉卡拉交易通知：" + reqBody);
            System.out.println(reqBody);

            JSONObject body = JSONObject.parseObject(reqBody);
            // 查询订单
            BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(body.getString("out_trade_no"));
            if (order != null && order.getStatus().equals(TradeOrderStatusEnum.status1.getNumber())) {
                Map<String,Object> other = new HashMap<>();
                other.put("log_no", body.getString("log_no"));
                other.put("acc_trade_no", body.getString("acc_trade_no"));
                other.put("card_type", body.getString("card_type"));

                if (body.getString("acc_settle_amount") != null) {
                    other.put("acc_settle_amount", body.getBigDecimal("acc_settle_amount").divide(new BigDecimal("100")));
                }
                if (body.getString("acc_discount_amount") != null) {
                    other.put("acc_discount_amount", body.getBigDecimal("acc_discount_amount").divide(new BigDecimal("100")));
                }
                if (body.getString("acc_mdiscount_amount") != null) {
                    other.put("acc_mdiscount_amount", body.getBigDecimal("acc_mdiscount_amount").divide(new BigDecimal("100")));
                }

                tradeOrderService.paySuccess(
                        body.getString("out_trade_no"),
                        body.getString("trade_no"),
                        PlatformTypeEnum.type1,
                        TradeOrderPayModeEnum.getNameByCode(body.getString("account_type")),
                        body.getBigDecimal("total_amount").divide(new BigDecimal("100")),
                        body.getString("merchant_no"),
                        other
                );
            }

            if (StringUtils.isNotBlank(order.getPayNotifyUrl())) {
                BsTradeOrder tradeOrder = openApiTradeOrderService.getOrderByOutTradeNo(order.getOutTradeNo());
                ResponseQueryTradeModel responseQueryTradeModel = new ResponseQueryTradeModel();
                responseQueryTradeModel.setMerchantNo(tradeOrder.getMerNo());
                responseQueryTradeModel.setOutTradeNo(tradeOrder.getOutTradeNo());
                responseQueryTradeModel.setAccTradeNo(tradeOrder.getAccTradeNo());
                responseQueryTradeModel.setUserId(tradeOrder.getPayUserId());
                responseQueryTradeModel.setPayMode(tradeOrder.getPayMode());
                responseQueryTradeModel.setTradeAmount(tradeOrder.getTradeAmount());
                responseQueryTradeModel.setTradeActualAmount(tradeOrder.getTradeActualAmount());
                responseQueryTradeModel.setStatus(tradeOrder.getStatus());
                responseQueryTradeModel.setCreateTime(tradeOrder.getCreateTime());
                responseQueryTradeModel.setPayTime(tradeOrder.getPayTime());
                responseQueryTradeModel.setAttach(tradeOrder.getAttach());
                responseQueryTradeModel.setSign(SignatureUtil.createSign(responseQueryTradeModel, merKeyService.getKeyByMerNo(tradeOrder.getMerNo())));

                log.info("发送URL：" +  order.getPayNotifyUrl());
                log.info("发送参数：" +  JSONObject.toJSONString(responseQueryTradeModel));
                JSONObject result = HttpsUtils.doPost(order.getPayNotifyUrl(), JSONObject.toJSONString(responseQueryTradeModel));
                if (result != null) {
                    log.info("响应参数：" +  result);
                    BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                    out.write(result.toJSONString().getBytes());
                    out.flush();
                    out.close();
                } else {
                    log.info("响应参数：null");
                }
            }

        } catch (Exception e) {
            log.info("出现异常", e);
        } finally {
            log.info("========= END 拉卡拉交易通知 END ===========");
        }
    }

    @RequestMapping(value="/tianque",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "天阙【随行付】交易通知")
    public void tianque(@RequestBody String reqBody, HttpServletResponse response) {
        try {
            log.info("========= Start 天阙【随行付】交易通知 Start ===========");
            log.info("平台接收天阙【随行付】交易通知：" + reqBody);
            System.out.println(reqBody);

            JSONObject body = JSONObject.parseObject(reqBody);
            // 查询订单
            BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(body.getString("ordNo"));
            if (order != null && order.getStatus().equals(TradeOrderStatusEnum.status1.getNumber())) {
                Map<String,Object> other = new HashMap<>();
                other.put("acc_trade_no", body.getString("transactionId"));
                other.put("card_type", body.getString("drType"));

                if (body.getString("acc_settle_amount") != null) {
                    other.put("acc_settle_amount", body.getBigDecimal("amt"));
                }
                if (body.getString("pointAmount") != null) {
                    other.put("acc_discount_amount", body.getBigDecimal("pointAmount"));
                }
                if (body.getString("clearDt") != null) {
                    other.put("settleDate", DateUtil.format(body.getString("clearDt"), "yyyyMMdd").getTime());
                }
                if (body.getString("settleAmt") != null) {
                    other.put("settleAmount", body.getBigDecimal("settleAmt"));
                }
                tradeOrderService.paySuccess(
                        body.getString("ordNo"),
                        body.getString("uuid"),
                        PlatformTypeEnum.type5,
                        TradeOrderPayModeEnum.getNameByCode(body.getString("payType")),
                        body.getBigDecimal("totalOffstAmt"),
                        body.getString("mno"),
                        other
                );
            }

            if (StringUtils.isNotBlank(order.getPayNotifyUrl())) {
                BsTradeOrder tradeOrder = openApiTradeOrderService.getOrderByOutTradeNo(order.getOutTradeNo());
                ResponseQueryTradeModel responseQueryTradeModel = new ResponseQueryTradeModel();
                responseQueryTradeModel.setMerchantNo(tradeOrder.getMerNo());
                responseQueryTradeModel.setOutTradeNo(tradeOrder.getOutTradeNo());
                responseQueryTradeModel.setAccTradeNo(tradeOrder.getAccTradeNo());
                responseQueryTradeModel.setUserId(tradeOrder.getPayUserId());
                responseQueryTradeModel.setPayMode(tradeOrder.getPayMode());
                responseQueryTradeModel.setTradeAmount(tradeOrder.getTradeAmount());
                responseQueryTradeModel.setTradeActualAmount(tradeOrder.getTradeActualAmount());
                responseQueryTradeModel.setStatus(tradeOrder.getStatus());
                responseQueryTradeModel.setCreateTime(tradeOrder.getCreateTime());
                responseQueryTradeModel.setPayTime(tradeOrder.getPayTime());
                responseQueryTradeModel.setAttach(tradeOrder.getAttach());
                responseQueryTradeModel.setSign(SignatureUtil.createSign(responseQueryTradeModel, merKeyService.getKeyByMerNo(tradeOrder.getMerNo())));

                log.info("发送URL：" +  order.getPayNotifyUrl());
                log.info("发送参数：" +  JSONObject.toJSONString(responseQueryTradeModel));
                JSONObject result = HttpsUtils.doPost(order.getPayNotifyUrl(), JSONObject.toJSONString(responseQueryTradeModel));
                if (result != null) {
                    log.info("响应参数：" +  result);
                    if (result.getString("code").equals("SUCCESS")
                            && result.getString("message").equals("执行成功")) {
                        result.put("code", "success");
                        result.put("message", "成功");
                        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                        out.write(result.toJSONString().getBytes());
                        out.flush();
                        out.close();
                    }
                } else {
                    log.info("响应参数：null");
                }
            }

        } catch (Exception e) {
            log.info("出现异常", e);
        } finally {
            log.info("========= END 天阙【随行付】交易通知 END ===========");
        }
    }

}
