package com.fs.app.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.fs.huifuPay.domain.HuiFuResult;
import com.fs.pay.pay.domain.OrderCallback;
import com.fs.pay.pay.domain.OrderResult;
import com.fs.pay.pay.dto.OrderQueryDTO;
import com.fs.pay.pay.service.PayService;
import com.fs.pay.service.IPayNotifyVerifyService;
import com.fs.pay.service.dto.PayNotifyDTO;
import com.fs.pay.service.dto.RefundNotifyDTO;
import com.fs.pay.service.dto.TradeOrder;
import com.fs.store.domain.FsStorePayment;
import com.fs.store.service.IFsStoreOrderService;
import com.fs.store.service.IFsStorePaymentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Api("第三方支付接口")
@RestController
@RequestMapping("/app/pay")
public class PayController {

    protected final Logger logger = LoggerFactory.getLogger(PayController.class);

    @Autowired
    private IFsStoreOrderService orderService;

    @Autowired
    private IFsStorePaymentService storePaymentService;

    @Autowired
    private PayService ybPayService;

    @Autowired
    private IPayNotifyVerifyService payNotifyVerifyService;


    @ApiOperation("易宝第三方支付回调")
    @PostMapping(value="/ybPayNotify")
    public String ybPayNotify(@RequestBody String body) {
        Map<String, String> params = JSON.parseObject(body, new TypeReference<Map<String, String>>() {});
        if (!payNotifyVerifyService.verifyYibaoCallback(params)) {
            logger.warn("易宝支付回调签名校验失败");
            return "fail";
        }
        OrderCallback o = JSON.parseObject(body, OrderCallback.class);
        OrderQueryDTO orderQueryDTO = new OrderQueryDTO();
        orderQueryDTO.setLowOrderId(o.getLowOrderId());
        OrderResult orderResult = ybPayService.getOrder(orderQueryDTO);
        String[] order=o.getLowOrderId().split("-");
        switch (order[0]) {
            case "store":
                return orderService.payConfirm(1,null,order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
            case "store_remain":
                return orderService.payRemainConfirm( order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
            case "payment":
                return storePaymentService.payConfirm(order[1],o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
        }
        return "SUCCESS";
    }

    @ApiOperation("汇付第三方支付回调")
    @PostMapping(value="/hfPayNotify")
    public String hfPayNotify(@RequestParam String resp_desc, @RequestParam String resp_code, @RequestParam String sign, @RequestParam String resp_data) {
        if (!payNotifyVerifyService.verifyHuifuCallback(resp_data, sign)) {
            logger.warn("汇付支付回调签名校验失败");
            return "fail";
        }
        HuiFuResult o = JSON.parseObject(resp_data, HuiFuResult.class);
        logger.info("汇付支付回调:"+o);
        if(o.getResp_code().equals("00000000")){
            String[] order=o.getReq_seq_id().split("-");
            switch (order[0]) {
                case "store":
                    return orderService.payConfirm(1,null,order[1], o.getHf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
                case "store_remain":
                    return orderService.payRemainConfirm( order[1], o.getHf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
                case "payment":
                    return storePaymentService.payConfirm(order[1],o.getHf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
            }
        }
        return "ok";
    }


    @ApiOperation("小雨点第三方支付回调")
    @PostMapping(value="/payNotify")
    public String payNotify(@RequestBody String body) {
        if (!payNotifyVerifyService.verifyHcPayCallback(body)) {
            logger.warn("小雨点支付回调签名校验失败");
            return "fail";
        }
        PayNotifyDTO dto = JSON.parseObject(body, PayNotifyDTO.class);
        if("SUCCESS".equals(dto.getOrderStatus())) {
            String tradeNo = dto.getMerchOrderNo();
            List<TradeOrder> tradeOrders= JSON.parseArray(dto.getTradeOrders(),TradeOrder.class);
            if(tradeOrders!=null&&tradeOrders.size()>0){
                for(TradeOrder tradeOrder:tradeOrders){
                    String[] order=tradeOrder.getSubMerchOrderNo().split("-");
                    switch (order[0]) {
                        case "store":
                            orderService.payConfirm(1,null,order[1], tradeNo,dto.getBankTransactionId(),dto.getBankSerialNo());
                            return "success";
                        case "store_remain":
                            orderService.payRemainConfirm( order[1], tradeNo,dto.getBankTransactionId(),dto.getBankSerialNo());
                            return "success";
                        case "payment":
                            return storePaymentService.payConfirm(order[1], tradeNo,dto.getBankTransactionId(),dto.getBankSerialNo());
                    }
                }
            }
        }
        return "success";
    }

    @ApiOperation("小雨点第三方退款回调")
    @PostMapping(value="/refundNotify")
    public String refundNotify(@RequestBody String body) throws Exception {
        if (!payNotifyVerifyService.verifyHcPayCallback(body)) {
            logger.warn("小雨点退款回调签名校验失败");
            return "fail";
        }
        RefundNotifyDTO dto = JSON.parseObject(body, RefundNotifyDTO.class);
        if("SUCCESS".equals(dto.getOrderStatus())) {
            String[] orderIds=dto.getOrigMerchOrderNo().split("-");
            FsStorePayment storePayment=null;
            switch (orderIds[0]) {
                case "store":
                    storePayment=storePaymentService.selectFsStorePaymentByCode(orderIds[1]);
                    if(storePayment!=null){
                        storePayment.setRefundMoney(BigDecimal.valueOf(Double.parseDouble(dto.getAmount())));
                        storePayment.setStatus(-1);
                        storePayment.setRefundTime(new Date());
                        storePaymentService.updateFsStorePayment(storePayment);
                    }
                    return "success";
                case "store_remain":
                    storePayment=storePaymentService.selectFsStorePaymentByCode(orderIds[1]);
                    if(storePayment!=null){
                        storePayment.setRefundMoney(BigDecimal.valueOf(Double.parseDouble(dto.getAmount())));
                        storePayment.setStatus(-1);
                        storePayment.setRefundTime(new Date());
                        storePaymentService.updateFsStorePayment(storePayment);
                    }
                    return "success";
                case "doctor":
                   return "success";
                case "payment":
                    storePaymentService.refund(orderIds[1]);
                    return "success";
            }
            return "success";
        }
        return "success";
    }

}
