package com.ghy.callback;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ghy.common.adapay.model.AdapayStatusEnum;
import com.ghy.common.adapay.model.Event;
import com.ghy.common.adapay.model.PayCallback;
import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.enums.PayStatus;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.service.CallBackService;
import com.ghy.payment.service.FinancialChangeRecordService;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture;

/**
 * 支付回调
 *
 * @author HH 2022/5/31
 */
@Service("payCallbackService")
public class PayCallbackService implements CallBackService {

    private static final Logger logger = LoggerFactory.getLogger(PayCallbackService.class);

    @Resource
    FinancialMasterService financialMasterService;

    @Resource
    FinancialDetailService financialDetailService;

    @Resource
    FinancialChangeRecordService financialChangeRecordService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onCallback(Event event) {
        logger.info("支付回调: {}", event);
        String data = event.getData();
        PayCallback payment = JSON.parseObject(data, PayCallback.class);
        PaymentDTO dto = financialMasterService.selectPaymentById(payment.getId());
        // 校验是否是本系统发出去的支付请求
        if (dto != null) {
            CompletableFuture.runAsync(() -> {
                // 异步更新交易记录 避免被回滚
                PaymentDTO param = new PaymentDTO();
                param.setId(payment.getId());
                param.setFeeAmt(payment.getFeeAmt());
                param.setStatus(payment.getStatus());
                param.setPayTime(LocalDateTime.now());
                financialMasterService.updatePayment(param);
            });
            if (AdapayStatusEnum.succeeded.code.equals(payment.getStatus())) {
                if (payment.getOrderNo().split("_").length > 2) {
                    // 支付回调中的加价记录ID
                    String fcrIdStr = payment.getOrderNo().split("_")[1];
                    String[] fcrIds = fcrIdStr.split(",");

                    BigDecimal totalChangeMoney = BigDecimal.ZERO;
                    Long financialMasterId = null;
                    for (String fcrId : fcrIds) {
                        FinancialChangeRecord financialChangeRecord = new FinancialChangeRecord();
                        financialChangeRecord.setId(Long.valueOf(fcrId));
                        financialChangeRecord.setPayStatus(1);
                        // 加价的支付paymentId回填到remark
                        financialChangeRecord.setRemark(payment.getId());
                        financialChangeRecord.setRemark(payment.getId());
                        financialChangeRecord.setPaymentId(payment.getId());
                        financialChangeRecordService.update(financialChangeRecord);

                        // 修改子订单的payMoney
                        FinancialChangeRecord fc = financialChangeRecordService.selectFinancialChangeRecordById(financialChangeRecord.getId());
                        FinancialDetail financialDetail = financialDetailService.selectByOrderDetailId(fc.getOrderDetailId());
                        FinancialDetail financialDetail2Update = new FinancialDetail();
                        financialDetail2Update.setId(financialDetail.getId());
                        financialDetail2Update.setPayMoney(financialDetail.getPayMoney().add(fc.getChangeMoney()));
                        financialDetail2Update.setPayStatus(PayStatus.PAID.getCode());
                        financialDetailService.updateFinancialDetail(financialDetail2Update);
                        totalChangeMoney = totalChangeMoney.add(fc.getChangeMoney());
                        if (financialMasterId == null) {
                            financialMasterId = financialDetail.getFinancialMasterId();
                        }
                    }
                    // 修改主单的payMoney
                    FinancialMaster financialMaster = financialMasterService.selectById(financialMasterId);
                    FinancialMaster financialMaster2Update = new FinancialMaster();
                    financialMaster2Update.setId(financialMaster.getId());
                    financialMaster2Update.setPayMoney(financialMaster.getPayMoney().add(totalChangeMoney));
                    financialMaster2Update.setPayStatus(PayStatus.PAID.getCode());
                    financialMasterService.updateFinancialMaster(financialMaster2Update);
                    // TODO 拆分对应的分账流水
                }
                // 更新主财务单状态
                financialMasterService.paySucceeded(payment.getId(), payment.getPayChannel());
            } else {
                logger.warn("支付失败 : {}", data);
            }
        } else {
            logger.warn("系统中不存在这条交易记录: {}", event);
        }
    }

    @Override
    public void onResponse(JSONObject response) {
        logger.info("发起支付 Response: {}", response.toJSONString());
        // 保存一条支付记录
        PaymentDTO payment = response.toJavaObject(PaymentDTO.class);
        String status = payment.getStatus();
        financialMasterService.insertPayment(payment);

        if (!AdapayStatusEnum.succeeded.code.equals(status)) {
            logger.warn("发起支付失败 : {}", response.toJSONString());
        }
    }

}
