package com.fs.store.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.fs.common.core.domain.R;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.ParseUtils;
import com.fs.common.utils.StringUtils;
import com.fs.company.service.ICompanyService;
import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
import com.fs.huifuPay.domain.HuiFuRefundResult;
import com.fs.huifuPay.dto.*;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.pay.bean.AliPayBean;
import com.fs.pay.pay.domain.OrderResult;
import com.fs.pay.pay.domain.RefundResult;
import com.fs.pay.pay.dto.OrderQueryDTO;
import com.fs.pay.pay.service.PayService;
import com.fs.store.domain.FsStoreOrder;
import com.fs.store.domain.TzConfigInfoDTO;
import com.fs.store.param.FsStorePaymentParam;
import com.fs.store.service.IFsStoreOrderService;
import com.fs.store.service.impl.FsCouponScheduleServiceImpl;
import com.fs.store.service.impl.FsStoreOrderServiceImpl;
import com.fs.store.vo.FsStorePaymentVO;
import com.fs.pay.service.IPayService;
import com.fs.tzBank.TzBankService;
import com.fs.tzBank.utils.TzConfigUtils;
import com.hc.openapi.tool.fastjson.JSON;
import com.ijpay.alipay.AliPayApi;
import com.ijpay.alipay.AliPayApiConfig;
import com.ijpay.alipay.AliPayApiConfigKit;
import io.swagger.annotations.ApiOperation;
import org.apache.http.util.Asserts;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import com.fs.common.annotation.Log;
import com.fs.common.core.controller.BaseController;
import com.fs.common.core.domain.AjaxResult;
import com.fs.common.enums.BusinessType;
import com.fs.store.domain.FsStorePayment;
import com.fs.store.service.IFsStorePaymentService;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.common.core.page.TableDataInfo;

/**
 * 支付明细Controller
 *
 * @author fs
 * @date 2022-06-25
 */
@RestController
@RequestMapping("/store/storePayment")
public class FsStorePaymentController extends BaseController
{
    @Autowired
    private IFsStorePaymentService fsStorePaymentService;
    @Autowired
    private IPayService payService;
    @Autowired
    private AliPayBean aliPayBean;
    @Autowired
    PayService ybPayService;
    @Autowired
    HuiFuService huiFuService;
    @Autowired
    TzBankService tzBankService;
    @Autowired
    private ICompanyService companyService;

    @Autowired
    private IFsStoreOrderService orderService;
    @Autowired
    private FsCouponScheduleServiceImpl fsCouponScheduleService;
    @Autowired
    private FsStoreOrderServiceImpl fsStoreOrderServiceImpl;
    @Autowired
    private FsStoreOrderServiceImpl fsStoreOrderService;

    /**
     * 查询支付明细列表
     */
    @PreAuthorize("@ss.hasPermi('store:storePayment:list')")
    @GetMapping("/list")
    public TableDataInfo list(FsStorePaymentParam fsStorePayment)
    {
        startPage();
        if(!StringUtils.isEmpty(fsStorePayment.getCreateTimeRange())){
            fsStorePayment.setCreateTimeList(fsStorePayment.getCreateTimeRange().split("--"));
        }
        List<FsStorePaymentVO> list = fsStorePaymentService.selectFsStorePaymentListQuery(fsStorePayment);
        for (FsStorePaymentVO vo : list){
            vo.setUserPhone(ParseUtils.parsePhone(vo.getUserPhone()));
        }
        return getDataTable(list);
    }

    /**
     * 导出支付明细列表
     */
    @PreAuthorize("@ss.hasPermi('store:storePayment:export')")
    @Log(title = "导出支付明细", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(FsStorePaymentParam fsStorePayment)
    {
        if(!StringUtils.isEmpty(fsStorePayment.getCreateTimeRange())){
            fsStorePayment.setCreateTimeList(fsStorePayment.getCreateTimeRange().split("--"));
        }
        List<FsStorePaymentVO> list = fsStorePaymentService.exportFsStorePaymentList(fsStorePayment);
        for (FsStorePaymentVO vo : list){
            vo.setUserPhone(ParseUtils.parsePhone(vo.getUserPhone()));
        }
        ExcelUtil<FsStorePaymentVO> util = new ExcelUtil<FsStorePaymentVO>(FsStorePaymentVO.class);
        return util.exportExcel(list, "storePayment");
    }

    /**
     * 获取支付明细详细信息
     */
    @PreAuthorize("@ss.hasPermi('store:storePayment:query')")
    @GetMapping(value = "/{paymentId}")
    public AjaxResult getInfo(@PathVariable("paymentId") Long paymentId)
    {
        return AjaxResult.success(fsStorePaymentService.selectFsStorePaymentById(paymentId));
    }


    @ApiOperation("支付手动通知")
@PreAuthorize("@ss.hasPermi('store:storePayment:payNotify')")
    @PostMapping("/returnPayStatus")
    public R returnPayStatus(@RequestBody FsStorePayment fsStorePayment) throws Exception
    {
        FsStorePayment payment=  fsStorePaymentService.selectFsStorePaymentByTradeNo(fsStorePayment.getTradeNo());
        if(payment == null) {
            throw new IllegalArgumentException("该付款记录没有查询到!");
        }
        String payMode = payment.getPayMode();
        logger.info("手动查询"+payment);
        if (payMode.equals("hf")){
            V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
            request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
            request.setOrgHfSeqId(payment.getTradeNo());
            HuiFuQueryOrderResult o = null;
            try {
                o = huiFuService.queryOrder(request);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            logger.info("汇付返回"+o);
            if ("00000000".equals(o.getResp_code())) {
                if (o.getTrans_stat().equals("S")) {
                    String[] order=o.getOrg_req_seq_id().split("-");
                    switch (order[0]) {
                        case "store":
                             orderService.payConfirm(1,null,order[1], o.getOrg_hf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
                             break;
                        case "store_remain":
                             orderService.payRemainConfirm( order[1], o.getOrg_hf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
                            break;
                        case "payment":
                             fsStorePaymentService.payConfirm(order[1],o.getOrg_hf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
                            break;
                    }
                    return R.ok();
                }
            }
        }else if (payMode.equals("yb")){
            OrderQueryDTO o = new OrderQueryDTO();
            o.setUpOrderId(payment.getTradeNo());
            OrderResult orderResult = ybPayService.getOrder(o);
            if (orderResult != null ){
                if ("4".equals(orderResult.getState())) {
                    return R.error("订单未支付");
                }
                if ("5".equals(orderResult.getState())) {
                    return R.error("订单已退款");
                }
                if ("0".equals(orderResult.getState())){
                    String[] order=orderResult.getLowOrderId().split("-");
                    if(orderResult.getStatus().equals("100")){
                        switch (order[0]) {
                            case "store":
                                orderService.payConfirm(1,null,order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
                                break;
                            case "store_remain":
                                orderService.payRemainConfirm( order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
                                break;
                            case "payment":
                                fsStorePaymentService.payConfirm(order[1],o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
                                break;
                        }
                        return R.ok();
                    }else {
                        return R.error("请检查外部订单号");
                    }
                }else {
                    return R.error("订单支付状态异常，联系财务检查");
                }
            }
        } else if(payMode.equals("tzbk")){
            FsStoreOrder fsStoreOrder = orderService.selectFsStoreOrderById(payment.getOrderId());
            Asserts.notNull(fsStoreOrder,"当前订单不存在!");

            RequestDTO<QueryOrderRestDTO> requestDTO = new RequestDTO<>();

            QueryOrderRestDTO queryOrderRestDTO = new QueryOrderRestDTO();
            queryOrderRestDTO.setOrderFlowNo(payment.getTradeNo());
            TzConfigInfoDTO tzConfigInfoDTO = TzConfigUtils.getConfig();

            queryOrderRestDTO.setPlatMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());

            requestDTO.setReqBody(queryOrderRestDTO);
            requestDTO.setReqHeader(TzReqHeaderDTO.getInstance(payment.getPayCode()));

            TzReqResultDTO<QueryOrderInfoDTO> resultDTO = tzBankService.payQueryOrder(requestDTO);
            String retCode = resultDTO.getRetCode();
            if(!retCode.equals("00000000")){
                logger.info("台州银行支付回调查询失败{}",resultDTO);
                throw new CustomException("台州银行支付回调查询失败! msg="+resultDTO.getRetCode());
            }
            QueryOrderInfoDTO body = resultDTO.getBody();

            orderService.payConfirm(1, fsStoreOrder.getId(), payment.getPayCode(),
                    payment.getTradeNo(),body.getChlTrxId(),payment.getTradeNo());
            return R.ok();
        }

        return R.error("请检查外部订单号");
    }



    /**
     * 新增支付明细
     */
    @PreAuthorize("@ss.hasPermi('store:storePayment:add')")
    @Log(title = "支付明细", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody FsStorePayment fsStorePayment)
    {
        return toAjax(fsStorePaymentService.insertFsStorePayment(fsStorePayment));
    }

    @PreAuthorize("@ss.hasPermi('store:storePayment:refund')")
    @PostMapping("refundStorePayment")
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public R refundStorePayment(@RequestBody FsStorePayment fsStorePayment)
    {
        FsStorePayment payment=fsStorePaymentService.selectFsStorePaymentById(fsStorePayment.getPaymentId());
        if(payment.getStatus()!=1){
            return R.error("非法操作");
        }
        if(fsStorePayment.getRefundMoney().compareTo(new BigDecimal(0))<1){
            return R.error("退款金额必须大于0");
        }
        if(payment.getPayMoney().compareTo(fsStorePayment.getRefundMoney())==-1){
            return R.error("退款金额必须小于等于付款金额");
        }
        if(payment.getPayTypeCode().equals("weixin")){
            if (payment.getPayMode()==null||payment.getPayMode().equals("yb")){
                com.fs.pay.pay.dto.RefundDTO refundDTO = new com.fs.pay.pay.dto.RefundDTO();
                refundDTO.setRefundMoney(fsStorePayment.getRefundMoney().toString());
                refundDTO.setLowRefundNo("refund-"+payment.getPayCode());
                refundDTO.setUpOrderId(payment.getTradeNo());
                RefundResult result=ybPayService.refund(refundDTO);
                if(result.getState().equals("5")||result.getState().equals("6")){
                    payment.setRefundMoney(fsStorePayment.getRefundMoney());
                    payment.setStatus(-1);
                    payment.setRefundTime(new Date());
                    fsStorePaymentService.updateFsStorePayment(payment);
                    //收款 减去所有
                    if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
                        companyService.subCompanyPaymentMoney(payment);
                    }
                    return R.ok();
                }
                else{
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return R.error(result.getMessage());
                }
            }else if (payment.getPayMode()!=null&&payment.getPayMode().equals("hf")){
                V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
                request.setOrdAmt(payment.getPayMoney().toString());
                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
                request.setReqSeqId("refund-"+payment.getPayCode());
                Map<String, Object> extendInfoMap = new HashMap<>();
                extendInfoMap.put("org_party_order_id", payment.getBankSerialNo());
                request.setExtendInfo(extendInfoMap);
                HuiFuRefundResult refund = huiFuService.refund(request);
                logger.info("退款："+refund);
                if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
                    payment.setRefundMoney(fsStorePayment.getRefundMoney());
                    payment.setStatus(-1);
                    payment.setRefundTime(new Date());
                    fsStorePaymentService.updateFsStorePayment(payment);
                    //收款 减去所有
                    if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
                        companyService.subCompanyPaymentMoney(payment);
                    }
                    return R.ok();
                }else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return R.error(refund.getResp_desc());
                }

            }else if (payment.getPayMode()!=null&&payment.getPayMode().equals("tzbk")){
                TzConfigInfoDTO tzConfigInfoDTO = TzConfigUtils.getConfig();

                RequestDTO<TzPayRefundDTO> requestDTO = new RequestDTO<TzPayRefundDTO>();
                TzPayRefundDTO tzPayRefundDTO = new TzPayRefundDTO();
                tzPayRefundDTO.setOldPayOutOrderNo(payment.getPayCode());
                tzPayRefundDTO.setRefundOrderNo(payment.getPayCode());
                tzPayRefundDTO.setPlatMerCstNo(tzConfigInfoDTO.getPlatMerCstNo());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                tzPayRefundDTO.setTrxSendTime(sdf.format(new Date()));
                tzPayRefundDTO.setRefundOrdTransAmt(payment.getPayMoney());
                tzPayRefundDTO.setNotifyURL(tzConfigInfoDTO.getRefundNotifyUrl());
                requestDTO.setReqBody(tzPayRefundDTO);
                requestDTO.setReqHeader(TzReqHeaderDTO.getInstance(payment.getPayCode()));

                TzReqResultDTO<TzRefundNotifyDTO> resultDTO;

                try {
                    // 退款将定时发放优惠券的状态设置为已退款
                    fsCouponScheduleService.setScheduleCouponRefund(String.valueOf(payment.getOrderId()));

                    resultDTO = tzBankService.payRefund(requestDTO);
                    TzRefundNotifyDTO body = resultDTO.getBody();
                    String refundOrdStatus = body.getRefundOrdStatus();
                    if("90".equals(refundOrdStatus) || "50".equals(refundOrdStatus)){
                        payment.setRefundMoney(fsStorePayment.getRefundMoney());
                        payment.setStatus(-1);
                        payment.setRefundTime(new Date());
                        fsStorePaymentService.updateFsStorePayment(payment);
                        //收款 减去所有
                        if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
                            companyService.subCompanyPaymentMoney(payment);
                        }
                    } else {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return R.error(resultDTO.getRetMsg());
                    }
                } catch (Exception e) {
                    throw new RuntimeException("退款请求失败"+e);
                }
            }
            //易宝退款

            //小雨点退款
//            payment.setRefundMoney(fsStorePayment.getRefundMoney());
//            fsStorePaymentService.updateFsStorePayment(payment);
//
//            RefundDTO refundDTO=new RefundDTO();
//            refundDTO.setMerchOrderNo(Ids.oid());
//            refundDTO.setAmount(fsStorePayment.getRefundMoney().toString());
//            refundDTO.setOrigMerchOrderNo("payment-"+payment.getPayCode());
//            return payService.refundOrder(refundDTO);
        }
        else if(payment.getPayTypeCode().equals("alipay")){
            try {
                AliPayApiConfig aliPayApiConfig;
                try {
                    aliPayApiConfig = AliPayApiConfigKit.getApiConfig(aliPayBean.getAppId());
                } catch (Exception e) {
                    aliPayApiConfig = AliPayApiConfig.builder()
                            .setAppId(aliPayBean.getAppId())
                            .setAliPayPublicKey(aliPayBean.getPublicKey())
                            .setAppCertPath(aliPayBean.getAppCertPath())
                            .setAliPayCertPath(aliPayBean.getAliPayCertPath())
                            .setAliPayRootCertPath(aliPayBean.getAliPayRootCertPath())
                            .setCharset("UTF-8")
                            .setPrivateKey(aliPayBean.getPrivateKey())
                            .setServiceUrl(aliPayBean.getServerUrl())
                            .setSignType("RSA2")
                            // 普通公钥方式
                            .build();
                    // 证书模式
//					.buildByCert();
                }
                AliPayApiConfigKit.putApiConfig(aliPayApiConfig);
                AlipayTradeRefundModel model = new AlipayTradeRefundModel();
                model.setOutTradeNo("payment-"+payment.getPayCode());
                model.setTradeNo(payment.getTradeNo());
                model.setRefundAmount(fsStorePayment.getRefundMoney().toString());
                model.setRefundReason("退款");
                String result=AliPayApi.tradeRefundToResponse(model).getBody();
                cn.hutool.json.JSONObject json= JSONUtil.parseObj(result);
                cn.hutool.json.JSONObject jsonInfo= (cn.hutool.json.JSONObject) json.get("alipay_trade_refund_response");
                String code=(String)jsonInfo.get("code");
                String msg=(String)jsonInfo.get("sub_msg");
                //{"alipay_trade_refund_response":{"code":"10000","msg":"Success","buyer_logon_id":"270***@qq.com","buyer_user_id":"2088402776950529","fund_change":"Y","gmt_refund_pay":"2022-04-27 18:27:28","out_trade_no":"goods-202204271826530001","refund_fee":"0.10","send_back_fee":"0.00","trade_no":"2022042722001450521456255417"},"sign":"hU+dy17/juMYQEQpO7Yy7jxkx9h5ebSbN3xdZr58msfOfJEUknqra6w4L37pgoZSx1Vj00jK3Ds06vrph6mSEliq3PQ37PwbZiRK3ZHaaKlz+9ndjoBTFYAxP60zLASfTq+W+dczDq4KOrvwhprFGt7YwKXGU42PgfOPb5EOgWyYUP6ivP0r06OzTo0f2lB28w6AQ4m4IQjdIL/tWbDaKl+ld8MPMLIgw5k9BmMcP8LV8ENC6+Gl1u5GwgAMjwHfk0RfB/kTFTHUTa7fgaO22w3pT8YKFMnOdKA0cVuJ2LE4SdxepqlprWJdCtLOeoQUX6PkEtoJGywPWAyjgdJ6Pg=="}
                if(code.equals("10000")){
                    payment.setRefundMoney(fsStorePayment.getRefundMoney());
                    fsStorePaymentService.updateFsStorePayment(payment);
                    fsStorePaymentService.refund(payment.getPayCode());
                    return R.ok("退款成功");

                }
                else{
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return R.error("退款失败:"+msg);

                }
                //退款成功
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
        }
        return R.error("非法操作");
    }


    /**
     * 修改支付明细
     */
    @PreAuthorize("@ss.hasPermi('store:storePayment:edit')")
    @Log(title = "支付明细", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody FsStorePayment fsStorePayment)
    {
        return toAjax(fsStorePaymentService.updateFsStorePayment(fsStorePayment));
    }

    /**
     * 删除支付明细
     */
    @PreAuthorize("@ss.hasPermi('store:storePayment:remove')")
    @Log(title = "支付明细", businessType = BusinessType.DELETE)
	@DeleteMapping("/{paymentIds}")
    public AjaxResult remove(@PathVariable Long[] paymentIds)
    {
        return toAjax(fsStorePaymentService.deleteFsStorePaymentByIds(paymentIds));
    }
}
