package com.liquidnet.service.platform.service.refund;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dto.param.RefundCallbackParam;
import com.liquidnet.service.kylin.dto.vo.returns.KylinOrderRefundsVo;
import com.liquidnet.service.kylin.entity.KylinOrderRefunds;
import com.liquidnet.service.kylin.entity.KylinOrderTickets;
import com.liquidnet.service.kylin.mapper.*;
import com.liquidnet.service.kylin.service.IKylinOrderRefundsService;
import com.liquidnet.service.platform.utils.DataUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 订单退款表 服务实现类 处理逻辑判断
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-05-26
 */
@Slf4j
@Service
public class OrderRefundsCallbackServiceImpl extends ServiceImpl<KylinOrderRefundsMapper, KylinOrderRefunds> implements IKylinOrderRefundsService {
    @Value("${liquidnet.client.admin.platformUrl}")
    private String platformUrl;
    @Value("${liquidnet.client.admin.phpPayUrl}")
    private String phpPayUrl;

    @Autowired
    private KylinRefundsStatusServiceImpl kylinRefundsStatusServiceImpl;

    @Autowired
    private KylinOrderRefundsMapper kylinOrderRefundsMapper;
    @Autowired
    private KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    private MongoConverter mongoConverter;
    @Autowired
    private DataUtils dataUtils;

    public String refundCallback(RefundCallbackParam refundCallbackParam) {
        KylinOrderRefunds refundInfo = kylinOrderRefundsMapper.selectOne(
                new UpdateWrapper<KylinOrderRefunds>()
                        .eq("order_refund_code", refundCallbackParam.getOrderRefundCode())
        );
        if (refundInfo == null) {
            log.info("Failed:{}.RefundController refundCallback: 退款订单查询失败，编号{}", "KylinOrderRefundsServiceImplRefundCallback", refundCallbackParam.getOrderRefundCode());
            return "fail";
        }
        if (refundInfo.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL || refundInfo.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT) {
            log.info("Failed:{}.RefundController refundCallback: 退款订单已取消或已运营审核拒绝，编号{}", "KylinOrderRefundsServiceImplRefundCallback", refundCallbackParam.getOrderRefundCode());
            return "fail";
        }
        if (refundInfo.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_REFUNDED) {
            log.info("Failed:{}.RefundController refundCallback: 退款订单已退款，编号{}", "KylinOrderRefundsServiceImplRefundCallback", refundCallbackParam.getOrderRefundCode());
            return "success";
        }

        Integer status = refundCallbackParam.getStatus();
        if (1 == status) { // 退款成功
            boolean res = kylinRefundsStatusServiceImpl.orderTicketRefunded(refundCallbackParam, refundInfo);
            if (res) {
                return "success";
            } else {
                return "fail";
            }
        }
        if (0 == status) { // 退款失败
            KylinOrderRefunds kylinOrderRefunds = new KylinOrderRefunds();
            kylinOrderRefunds.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR);
            kylinOrderRefunds.setRefundCode(refundCallbackParam.getRefundCode());
            kylinOrderRefunds.setRefundAt(refundCallbackParam.getRefundAt());
            kylinOrderRefunds.setRefundError(refundCallbackParam.getRefundError());
            kylinOrderRefunds.setUpdatedAt(LocalDateTime.now());
            kylinOrderRefundsMapper.update(
                    kylinOrderRefunds,
                    new UpdateWrapper<KylinOrderRefunds>().eq("order_refunds_id", refundInfo.getOrderRefundsId())
            );
            // 修改缓存
            KylinOrderRefundsVo kylinOrderRefundsVo = new KylinOrderRefundsVo();
            BeanUtils.copyProperties(kylinOrderRefunds, kylinOrderRefundsVo);
            BasicDBObject object = new BasicDBObject("$set", mongoConverter.convertToMongoType(kylinOrderRefundsVo));
            UpdateResult updateResult = mongoTemplate.getCollection(KylinOrderRefundsVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderRefundsId").is(refundInfo.getOrderRefundsId())).getQueryObject(),
                    object
            );
            dataUtils.delOrderRefundVo(refundInfo.getOrderRefundsId());
            dataUtils.delOrderRefundVoByOrderId(refundInfo.getOrderTicketsId());
        }
        return "success";
    }

    @Override
    public String getOrderRefundCode(String orderRefundCode,int type) {
        return null;
    }

    public String alipayActiveCallback() {
        LocalDateTime startTime =  LocalDateTime.now();
        LocalDateTime newTime = startTime.minusHours(8);
        List<KylinOrderRefunds> kylinOrderRefunds = kylinOrderRefundsMapper.selectList(
                Wrappers.lambdaQuery(KylinOrderRefunds.class)
                        .eq(KylinOrderRefunds::getStatus, KylinTableStatusConst.ORDER_REFUND_STATUS_UNFILLED)
                        .lt(KylinOrderRefunds::getExecutorAt, newTime) // 默认减去8小时的
        );
        for (KylinOrderRefunds refundInfo : kylinOrderRefunds) {
            KylinOrderTickets orderInfo = kylinOrderTicketsMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderTickets.class)
                            .eq(KylinOrderTickets::getOrderTicketsId, refundInfo.getOrderTicketsId())
            );
            if (null != orderInfo.getPaymentType() && (orderInfo.getPaymentType().equals("WAPALIPAY") || orderInfo.getPaymentType().equals("APPALIPAY"))) {
                log.info("\n支付宝退款主动查询处理结果：\n[{}] ", orderInfo.getOrderTicketsId());
                MultiValueMap<String, String> params = new LinkedMultiValueMap();
                params.add("callBackUrl", platformUrl.concat("/platform/refund/callback"));
                params.add("orderCode", orderInfo.getOrderCode());
                params.add("orderRefundCode", refundInfo.getOrderRefundCode());
                params.add("paymentId", orderInfo.getPaymentId());

                // log.info("退款参数" + JsonUtils.toJson(params));
                log.info("\n支付宝退款主动查询参数：\n[{}] ", params.toString());
                // 请求pay
                try {
                    String postResult = HttpUtil.post(phpPayUrl.concat("/dragon/refund/refund/alipay/result"), params);
                    log.info("\n支付宝退款主动查询处理结果：\n[{}] " + postResult);
                } catch (Exception e) {
                    log.info("\n支付宝退款主动查询失败：[errorMsg=[{}], [orderRefundsId=[{}]", e.getMessage(), refundInfo.getOrderRefundsId());
                }

            }
        }
        return "success";
    }
}
