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.order.domain.OrderAddSubtract;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.mapper.OrderMasterMapper;
import com.ghy.order.service.IOrderAddSubtractService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.domain.PaymentRelation;
import com.ghy.payment.mapper.PaymentRelationMapper;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

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

    @Resource
    OrderMasterService orderMasterService;

    @Resource
    FinancialMasterService financialMasterService;
    @Resource
    PaymentRelationMapper paymentRelationMapper;
    @Resource
    FinancialDetailService financialDetailService;
    @Resource
    IOrderAddSubtractService orderAddSubtractService;
    @Resource
    FinancialChangeRecordService financialChangeRecordService;

    @Override
    public void onCallback(Event event) {
        log.info("支付回调: {}", event);
        String data = event.getData();
        PayCallback payment = JSON.parseObject(data, PayCallback.class);
        PaymentDTO dto = financialMasterService.selectPaymentById(payment.getId());
        // 支付ID
        final String paymentId = dto.getId();
        // 是否支付成功
        final boolean succeeded = AdapayStatusEnum.succeeded.code.equals(payment.getStatus());

        // 异步更新交易记录 避免被其它业务异常回滚
        CompletableFuture.runAsync(() -> {
            PaymentDTO param = new PaymentDTO();
            param.setId(payment.getId());
            param.setStatus(payment.getStatus());
            if (succeeded) {
                // 如果支付成功 更新支付渠道、支付时间、手续费
                param.setPayChannel(payment.getPayChannel());
                param.setFeeAmt(payment.getFeeAmt());
                param.setPayTime(LocalDateTime.now());
                if ("delay".equals(dto.getPayMode())) {
                    // 如果支付成功 且是延迟分账模式 更新可用金额=交易金额
                    param.setAvailableAmt(dto.getPayAmt());
                }
            }
            financialMasterService.updatePayment(param);
        });

        if (succeeded) {
            // 支付成功 查询支付关联的订单
            List<PaymentRelation> paymentRelations = paymentRelationMapper.selectByPaymentId(paymentId);
            if (CollectionUtils.isEmpty(paymentRelations)) {
                log.error("未关联订单的支付回调: {}", data);
                return;
            }

            for (PaymentRelation relation : paymentRelations) {
                Long relationId = relation.getRelationId();
                if (PaymentRelation.FINANCIAL_MASTER.equals(relation.getRelationIdType())) {
                    FinancialMaster financialMaster = financialMasterService.selectById(relationId);
                    // 更新主订单的支付信息
                    orderMasterService.updatePayStatus(financialMaster.getOrderMasterId(), PayStatus.PAID.getCode());
                    // 更新主财务单的支付信息
                    financialMasterService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
                    log.info("主财务单[{}]支付成功", relationId);
                    
                    // 检查是否为商品订单且有关联的服务订单，需要同步更新服务订单财务主单支付状态
                    try {
                        OrderMaster orderMaster = orderMasterService.selectById(financialMaster.getOrderMasterId());
                        if (orderMaster != null && orderMaster.getOrderType() == 1 && orderMaster.getHasServiceOrder() == 1) {
                            // 查询关联的服务订单
                            OrderMaster serviceOrder = orderMasterService.selectByGoodsOrderMasterId(orderMaster.getId());
                            if (serviceOrder != null) {
                                    // 查询服务订单对应的财务主单
                                    FinancialMaster serviceFinancialMaster = financialMasterService.selectByOrderMasterId(serviceOrder.getId());
                                    if (serviceFinancialMaster != null && !PayStatus.PAID.getCode().equals(serviceFinancialMaster.getPayStatus())) {
                                        // 更新服务订单财务主单支付状态
                                        financialMasterService.updatePay(serviceFinancialMaster.getId(), paymentId, PayStatus.PAID.getCode());
                                        // 更新服务订单支付状态
                                        orderMasterService.updatePayStatus(serviceOrder.getId(), PayStatus.PAID.getCode());
                                        log.info("商品订单[{}]关联的服务订单[{}]财务主单[{}]支付状态已同步更新为已支付", 
                                                orderMaster.getId(), serviceOrder.getId(), serviceFinancialMaster.getId());
                                    }
                                }
                            
                        }
                    } catch (Exception e) {
                        log.error("同步更新商品订单关联服务订单支付状态时发生异常，商品订单ID: {}, 异常信息: {}", 
                                financialMaster.getOrderMasterId(), e.getMessage(), e);
                    }

                } else if (PaymentRelation.FINANCIAL_CHANGE.equals(relation.getRelationIdType())) {

                    // 更新加价单的支付信息
                    financialChangeRecordService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
                    FinancialChangeRecord fc = financialChangeRecordService.selectFinancialChangeRecordById(relationId);
                    // 修改子订单的payMoney
                    FinancialDetail fd = financialDetailService.selectByOrderDetailId(fc.getOrderDetailId());
                    FinancialDetail fd2Update = new FinancialDetail();
                    fd2Update.setId(fd.getId());
                    fd2Update.setPayMoney(fd.getPayMoney());
                    fd2Update.setPayStatus(PayStatus.PAID.getCode());
                    financialDetailService.updateFinancialDetail(fd2Update);
                    // 修改主单的payMoney
                    FinancialMaster financialMaster = financialMasterService.selectById(fd.getFinancialMasterId());
                    FinancialMaster financialMaster2Update = new FinancialMaster();
                    financialMaster2Update.setId(financialMaster.getId());
                    financialMaster2Update.setPayMoney(financialMaster.getPayMoney());
                    financialMaster2Update.setPayStatus(PayStatus.PAID.getCode());
                    financialMasterService.updateFinancialMaster(financialMaster2Update);
                    // 更新主订单的支付信息
                    orderMasterService.updatePayStatus(financialMaster.getOrderMasterId(), PayStatus.PAID.getCode());
                    log.info("FinancialChange[{}]支付成功", relationId);

                } else if (PaymentRelation.ORDER_ADD.equals(relation.getRelationIdType())) {
                    // 更新订单追加单的支付信息
                    orderAddSubtractService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
                    OrderAddSubtract orderAdd = orderAddSubtractService.selectById(relationId);
                    // 修改子订单的payMoney
                    FinancialDetail fd = financialDetailService.selectByOrderDetailId(orderAdd.getOrderDetailId());
                    FinancialDetail fd2Update = new FinancialDetail();
                    fd2Update.setId(fd.getId());
                    fd2Update.setPayMoney(fd.getPayMoney());
                    fd2Update.setPayStatus(PayStatus.PAID.getCode());
                    financialDetailService.updateFinancialDetail(fd2Update);
                    // 修改主单的payMoney
                    FinancialMaster financialMaster = financialMasterService.selectById(fd.getFinancialMasterId());
                    FinancialMaster financialMaster2Update = new FinancialMaster();
                    financialMaster2Update.setId(financialMaster.getId());
                    financialMaster2Update.setPayMoney(financialMaster.getPayMoney());
                    financialMaster2Update.setPayStatus(PayStatus.PAID.getCode());
                    financialMasterService.updateFinancialMaster(financialMaster2Update);
                    log.info("订单追加[{}]支付成功", relationId);

                } else if (PaymentRelation.CONSULT_ADD.equals(relation.getRelationIdType())) {
                    // 更新加价单的支付信息
                    financialChangeRecordService.updatePay(relationId, paymentId, PayStatus.PAID.getCode());
                } else {
                    log.error("未知的订单类型: relationIdType={}, relationId={}", relation.getRelationIdType(), relationId);
                }
            }
        }
    }

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

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

}
