package com.liquidnet.service.kylin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dto.param.RefundCallbackParam;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketEntitiesVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketVo;
import com.liquidnet.service.kylin.entity.KylinOrderRefunds;
import com.liquidnet.service.kylin.entity.KylinOrderTicketEntities;
import com.liquidnet.service.kylin.entity.KylinOrderTicketStatus;
import com.liquidnet.service.kylin.entity.KylinOrderTickets;
import com.liquidnet.service.kylin.mapper.KylinOrderRefundsMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketEntitiesMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketStatusMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper;
import com.liquidnet.service.kylin.utils.DataUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * <p>
 * 订单退款表 服务实现类 处理数据 退款后状态的变化
 * </p>
 *
 * @author jiaangxiulong
 * @since 2021-05-26
 */
@Slf4j
@Service
public class KylinRefundsStatusServiceImpl {

    @Autowired
    private KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    private KylinOrderTicketStatusMapper kylinOrderTicketStatusMapper;

    @Autowired
    private KylinOrderRefundsMapper kylinOrderRefundsMapper;

    @Autowired
    private KylinOrderTicketEntitiesMapper kylinOrderTicketEntitiesMapper;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private DataUtils dataUtils;

    public boolean orderTicketRefunded(RefundCallbackParam refundCallbackParam, KylinOrderRefunds refundInfo) {
        String orderTicketEntitiesIds = refundInfo.getOrderTicketEntitiesIds();
        String[] orderTicketEntitiesIdsArr = orderTicketEntitiesIds.split(",");
        Integer EntitiesIdsCount = orderTicketEntitiesIdsArr.length;
        String orderTicketsId = refundInfo.getOrderTicketsId();

        // 更新数据
        // 订单状态表
        KylinOrderTickets orderInfo = kylinOrderTicketsMapper.selectOne(
                new QueryWrapper<KylinOrderTickets>().eq("order_tickets_id", orderTicketsId)
        );
        KylinOrderTicketStatus orderStatusTable = new KylinOrderTicketStatus();
        int newStatus = 0;
        if (EntitiesIdsCount + orderInfo.getRefundNumber() == orderInfo.getNumber()) {
            newStatus = KylinTableStatusConst.ORDER_STATUS4;
        } else {
            newStatus = KylinTableStatusConst.ORDER_STATUS6;
        }
        orderStatusTable.setStatus(newStatus);
        kylinOrderTicketStatusMapper.update(
                orderStatusTable, new UpdateWrapper<KylinOrderTicketStatus>()
                        .eq("order_id", orderTicketsId)
        );

        // 订单表
        double price = orderInfo.getPriceRefund().doubleValue() + refundInfo.getPrice().doubleValue();
        Integer num = orderInfo.getRefundNumber() + EntitiesIdsCount;
        KylinOrderTickets update = new KylinOrderTickets();
        update.setRefundNumber(num);
        update.setPriceRefund(BigDecimal.valueOf(price));
        kylinOrderTicketsMapper.update(
                update, new UpdateWrapper<KylinOrderTickets>()
                        .eq("order_tickets_id", orderTicketsId)
        );
        KylinOrderTicketVo kylinOrderTicketVoOrder = new KylinOrderTicketVo();
        kylinOrderTicketVoOrder.setStatus(newStatus);
        kylinOrderTicketVoOrder.setRefundNumber(num);
//        kylinOrderTicketVoOrder.setPriceRefund(BigDecimal.valueOf(price));
        BasicDBObject orderEntitiesObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketVoOrder)));
        Document docOrder = mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).findOneAndUpdate(
                Query.query(Criteria.where("orderTicketsId").is(orderTicketsId)).getQueryObject(),
                orderEntitiesObject,
                new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
        );
        dataUtils.delOrderTicketRedis(orderTicketsId);

        // 入场人
        for (String entitiesId : orderTicketEntitiesIdsArr) {
            KylinOrderTicketEntities entitiesTable = new KylinOrderTicketEntities();
            // TODO: 2021/5/27 事物 and 部分退款
            entitiesTable.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT3);
            kylinOrderTicketEntitiesMapper.update(entitiesTable, new UpdateWrapper<KylinOrderTicketEntities>()
                    .eq("order_ticket_entities_id", entitiesId)
                    .eq("is_payment", KylinTableStatusConst.ENTITIES_IS_PAYMENT2)
            );

            KylinOrderTicketEntitiesVo kylinOrderTicketEntitiesVo = new KylinOrderTicketEntitiesVo();
            kylinOrderTicketEntitiesVo.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT3);
            BasicDBObject entitiesObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketEntitiesVo)));
            Document entitiesDoc = mongoTemplate.getCollection(KylinOrderTicketEntitiesVo.class.getSimpleName()).findOneAndUpdate(
                    Query.query(Criteria.where("orderTicketEntitiesId").is(entitiesId)).getQueryObject(),
                    entitiesObject,
                    new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
            );

            dataUtils.delOrderTicketEntitiesRedis(entitiesId);
        }

        // 退款单完成
        KylinOrderRefunds kylinOrderRefunds = new KylinOrderRefunds();
        kylinOrderRefunds.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_REFUNDED);
        kylinOrderRefunds.setRefundCode(refundCallbackParam.getRefund_code());
        kylinOrderRefunds.setRefundType(refundCallbackParam.getRefund_type());
        kylinOrderRefunds.setRefundId(refundCallbackParam.getRefund_id());
        kylinOrderRefunds.setRefundAt(refundCallbackParam.getRefund_at());
        kylinOrderRefunds.setRefundError(refundCallbackParam.getRefund_error());

        kylinOrderRefundsMapper.update(
                kylinOrderRefunds,
                new UpdateWrapper<KylinOrderRefunds>().in("order_refunds_id", refundInfo.getOrderRefundsId())
        );

        if (refundInfo.getType() == KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY) {
            // 退还库存
            for (String entitiesId : orderTicketEntitiesIdsArr) {
                dataUtils.changeSurplusGeneral(entitiesId, 1);
            }
        }

        return true;
    }
}
