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

import com.alibaba.fastjson.JSON;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dto.vo.mongo.*;
import com.liquidnet.service.kylin.dto.vo.returns.KylinOrderRefundsVo;
import com.liquidnet.service.kylin.entity.*;
import com.liquidnet.service.kylin.utils.DataUtils;
import com.liquidnet.service.kylin.utils.OrderUtils;
import com.liquidnet.service.kylin.utils.QueueUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
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;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;

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

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private DataUtils dataUtils;

    @Autowired
    private OrderUtils orderUtils;
    @Autowired
    private QueueUtils queueUtils;

    public String userOrderTicketRefunding(
            KylinOrderTicketVo orderInfo,
            BigDecimal refundPrice,
            BigDecimal priceExpress,
            BigDecimal priceCharges,
            String orderEntitiesId,
            String reason,
            String picList,
            String uid,
            String username,
            int refundCount
    ) {
        try {
            LocalDateTime time = LocalDateTime.now();
            String strTime = DateUtil.getNowTime();
            // 订单状态表 缓存
            KylinOrderTicketStatus orderStatusTable = KylinOrderTicketStatus.getNew();
            orderStatusTable.setStatus(KylinTableStatusConst.ORDER_STATUS3);
            orderStatusTable.setUpdatedAt(time);


            KylinOrderTicketVo kylinOrderTicketVo = KylinOrderTicketVo.getNew();
            kylinOrderTicketVo.setStatus(KylinTableStatusConst.ORDER_STATUS3);
            kylinOrderTicketVo.setUpdatedAt(strTime);
            BasicDBObject orderObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketVo)));
            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketsId").is(orderInfo.getOrderTicketsId())).getQueryObject(),
                    orderObject
            );
            dataUtils.delOrderTicketRedis(orderInfo.getOrderTicketsId());

            // 订单入场人表 和 缓存
            KylinOrderTicketEntities entitiesTable = new KylinOrderTicketEntities();
            entitiesTable.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT2);
            entitiesTable.setUpdatedAt(time);

            KylinOrderTicketEntitiesVo kylinOrderTicketEntitiesVo = KylinOrderTicketEntitiesVo.getNew();
            kylinOrderTicketEntitiesVo.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT2);
            kylinOrderTicketEntitiesVo.setUpdatedAt(strTime);
            BasicDBObject entitiesObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketEntitiesVo)));
            mongoTemplate.getCollection(KylinOrderTicketEntitiesVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketEntitiesId").is(orderEntitiesId)).getQueryObject(),
                    entitiesObject
            );
            dataUtils.delOrderTicketEntitiesRedis(orderEntitiesId);

            orderUtils.resetOrderListVo(orderInfo.getUserId(), 2, orderInfo.getOrderTicketsId(), null);

            // 退款明细
            KylinOrderRefunds kylinOrderRefunds = new KylinOrderRefunds();
            String orderRefundsId = IDGenerator.nextSnowId();
            kylinOrderRefunds.setOrderRefundsId(orderRefundsId);
            kylinOrderRefunds.setOrderTicketsId(orderInfo.getOrderTicketsId());
            String orderRefundCode = orderInfo.getOrderCode();
            String codeNum = StringUtils.leftPad(String.valueOf(refundCount), 3, "0");
            kylinOrderRefunds.setOrderRefundCode(orderRefundCode.concat(codeNum));
            kylinOrderRefunds.setPrice(refundPrice);
            kylinOrderRefunds.setPriceExpress(priceExpress);
            kylinOrderRefunds.setPriceCharges(priceCharges);
            kylinOrderRefunds.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY);
            kylinOrderRefunds.setType(KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY);
            kylinOrderRefunds.setApplicantId(uid);
            kylinOrderRefunds.setApplicantName(username);
            kylinOrderRefunds.setApplicantAt(time);
            kylinOrderRefunds.setReason(reason);
            kylinOrderRefunds.setCreatedAt(time);

            KylinOrderRefundsVo orderRefundsVo = KylinOrderRefundsVo.getNew();
            BeanUtils.copyProperties(kylinOrderRefunds, orderRefundsVo);
            orderRefundsVo.setCreatedAt(time);
            orderRefundsVo.setApplicantAt(time);
            mongoTemplate.insert(orderRefundsVo, KylinOrderRefundsVo.class.getSimpleName());


            // 退款入场人表
            KylinOrderRefundEntities kylinOrderRefundEntities = KylinOrderRefundEntities.getNew();
            String orderRefundsEntitiesId = IDGenerator.nextSnowId();
            kylinOrderRefundEntities.setOrderRefundsEntitiesId(orderRefundsEntitiesId);
            kylinOrderRefundEntities.setOrderRefundsId(orderRefundsId);
            kylinOrderRefundEntities.setRefundPrice(refundPrice);
            kylinOrderRefundEntities.setOrderTicketEntitiesId(orderEntitiesId);
            kylinOrderRefundEntities.setCreatedAt(time);

            KylinOrderRefundEntitiesVo orderRefundEntitiesVo = KylinOrderRefundEntitiesVo.getNew();
            BeanUtils.copyProperties(kylinOrderRefundEntities, orderRefundEntitiesVo);
            orderRefundEntitiesVo.setCreatedAt(strTime);
            mongoTemplate.insert(orderRefundEntitiesVo, KylinOrderRefundEntitiesVo.class.getSimpleName());

            //退款图片
            KylinOrderRefundPic orderRefundPic = KylinOrderRefundPic.getNew();
            orderRefundPic.setRefundPicId(IDGenerator.nextSnowId());
            orderRefundPic.setOrderRefundsId(kylinOrderRefunds.getOrderRefundsId());
            orderRefundPic.setPicUrl(picList);
            orderRefundPic.setCreatedAt(time);

            KylinOrderRefundPicVo orderRefundPicVo = KylinOrderRefundPicVo.getNew();
            BeanUtils.copyProperties(orderRefundPic, orderRefundPicVo);
            orderRefundPicVo.setCreatedAt(strTime);
            mongoTemplate.insert(orderRefundPicVo, KylinOrderRefundPicVo.class.getSimpleName());

            dataUtils.delOrderRefundVoByOrderId(orderInfo.getOrderTicketsId());

            //MQ
            LinkedList<String> sqls = CollectionUtil.linkedListString();
            LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataC = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataD = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataE = CollectionUtil.linkedListObjectArr();

            sqls.add(SqlMapping.get("kylin_order_ticket_status.refund"));
            sqls.add(SqlMapping.get("kylin_order_ticket_entities.refund"));
            sqls.add(SqlMapping.get("kylin_order_refund.refund"));
            sqls.add(SqlMapping.get("kylin_order_refund_entities.refund"));
            sqls.add(SqlMapping.get("kylin_order_refund_pic.refund"));

            LocalDateTime now1 = LocalDateTime.now();
            sqlsDataA.add(new Object[]{
                    orderStatusTable.getStatus(), orderStatusTable.getUpdatedAt(), orderInfo.getOrderTicketsId(),now1, now1
            });
            sqlsDataB.add(new Object[]{
                    entitiesTable.getIsPayment(), entitiesTable.getUpdatedAt(), orderEntitiesId,now1, now1
            });
            sqlsDataC.add(new Object[]{
                    kylinOrderRefunds.getOrderRefundsId(), kylinOrderRefunds.getOrderTicketsId(), kylinOrderRefunds.getOrderRefundCode(),
                    kylinOrderRefunds.getPrice(), kylinOrderRefunds.getPriceExpress(), kylinOrderRefunds.getPriceCharges(), kylinOrderRefunds.getStatus(),
                    kylinOrderRefunds.getType(), kylinOrderRefunds.getApplicantId(), kylinOrderRefunds.getApplicantName(),
                    kylinOrderRefunds.getApplicantAt(), kylinOrderRefunds.getReason(), kylinOrderRefunds.getCreatedAt()
            });
            sqlsDataD.add(new Object[]{
                    kylinOrderRefundEntities.getOrderRefundsEntitiesId(), kylinOrderRefundEntities.getOrderRefundsId(), kylinOrderRefundEntities.getRefundPrice(),
                    kylinOrderRefundEntities.getOrderTicketEntitiesId(), kylinOrderRefundEntities.getCreatedAt()
            });
            sqlsDataE.add(new Object[]{
                    orderRefundPic.getOrderRefundsId(), orderRefundPic.getOrderRefundsId(), orderRefundPic.getPicUrl(), orderRefundPic.getCreatedAt()
            });

            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_ORDER_REFUND.getKey(),
                    SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC, sqlsDataD, sqlsDataE));

            return kylinOrderRefunds.getOrderRefundsId();
        } catch (Exception e) {
            log.error("userOrderTicketRefundingException e:[{}]", e);
            return "";
        }
    }

    public String userOrderTicketRefunding(
            KylinOrderTicketVo orderInfo,
            double refundPrice,
            String orderEntitiesId,
            String reason,
            String picList,
            String uid,
            String username,
            int refundCount
    ) {
        try {
            LocalDateTime time = LocalDateTime.now();
            String strTime = DateUtil.Formatter.yyyyMMddHHmmss.format(time);
            // 订单状态表 和 缓存
            KylinOrderTicketStatus orderStatusTable = new KylinOrderTicketStatus();
            orderStatusTable.setStatus(KylinTableStatusConst.ORDER_STATUS3);
            orderStatusTable.setUpdatedAt(time);


            KylinOrderTicketVo kylinOrderTicketVo = KylinOrderTicketVo.getNew();
            kylinOrderTicketVo.setStatus(KylinTableStatusConst.ORDER_STATUS3);
            kylinOrderTicketVo.setUpdatedAt(DateUtil.Formatter.yyyyMMddHHmmss.format(time));
            BasicDBObject orderObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketVo)));
            mongoTemplate.getCollection(KylinOrderTicketVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketsId").is(orderInfo.getOrderTicketsId())).getQueryObject(),
                    orderObject
            );
            dataUtils.delOrderTicketRedis(orderInfo.getOrderTicketsId());
            log.info("orderInfo.getUserId() = "+ orderInfo.getUserId());
            orderUtils.resetOrderListVo(orderInfo.getUserId(), 2, orderInfo.getOrderTicketsId(), null);


            // 订单入场人表 和 缓存
            KylinOrderTicketEntities entitiesTable = new KylinOrderTicketEntities();
            entitiesTable.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT2);
            entitiesTable.setUpdatedAt(time);

//            BigDecimal oldRefundPrice = BigDecimal.valueOf(0);
//            for (KylinOrderTicketEntitiesVo item :orderInfo.getEntitiesVoList()) {
//                if(item.getOrderTicketEntitiesId().equalsIgnoreCase(orderEntitiesId)){
//                    oldRefundPrice = item.getRefundPrice();
//                    break;
//                }
//            }


            KylinOrderTicketEntitiesVo kylinOrderTicketEntitiesVo = KylinOrderTicketEntitiesVo.getNew();
            kylinOrderTicketEntitiesVo.setIsPayment(KylinTableStatusConst.ENTITIES_IS_PAYMENT2);
//            kylinOrderTicketEntitiesVo.setRefundPrice(oldRefundPrice.add(BigDecimal.valueOf(refundPrice)));
            kylinOrderTicketEntitiesVo.setUpdatedAt(strTime);
            BasicDBObject entitiesObject = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(kylinOrderTicketEntitiesVo)));
            mongoTemplate.getCollection(KylinOrderTicketEntitiesVo.class.getSimpleName()).updateOne(
                    Query.query(Criteria.where("orderTicketEntitiesId").is(orderEntitiesId)).getQueryObject(),
                    entitiesObject
            );
            dataUtils.delOrderTicketEntitiesRedis(orderEntitiesId);

            // 退款明细
            KylinOrderRefunds kylinOrderRefunds = new KylinOrderRefunds();
            String orderRefundsId = IDGenerator.nextSnowId();
            kylinOrderRefunds.setOrderRefundsId(orderRefundsId);
            kylinOrderRefunds.setOrderTicketsId(orderInfo.getOrderTicketsId());
            String orderRefundCode = orderInfo.getOrderCode();
            String codeNum = StringUtils.leftPad(String.valueOf(refundCount), 3, "0");
            kylinOrderRefunds.setOrderRefundCode(orderRefundCode.concat(codeNum));
            kylinOrderRefunds.setPrice(BigDecimal.valueOf(refundPrice));
            kylinOrderRefunds.setPriceExpress(orderInfo.getPriceExpress());
            kylinOrderRefunds.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY);
            kylinOrderRefunds.setType(KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY);
            kylinOrderRefunds.setApplicantId(uid);
            kylinOrderRefunds.setApplicantName(username);
            kylinOrderRefunds.setApplicantAt(time);
            kylinOrderRefunds.setReason(reason);
            kylinOrderRefunds.setCreatedAt(time);

            KylinOrderRefundsVo orderRefundsVo = KylinOrderRefundsVo.getNew();
            BeanUtils.copyProperties(kylinOrderRefunds, orderRefundsVo);
            orderRefundsVo.setCreatedAt(time);
            orderRefundsVo.setApplicantAt(time);
            mongoTemplate.insert(orderRefundsVo, KylinOrderRefundsVo.class.getSimpleName());


            // 退款入场人表
            KylinOrderRefundEntities kylinOrderRefundEntities = new KylinOrderRefundEntities();
            String orderRefundsEntitiesId = IDGenerator.nextSnowId();
            kylinOrderRefundEntities.setOrderRefundsEntitiesId(orderRefundsEntitiesId);
            kylinOrderRefundEntities.setOrderRefundsId(orderRefundsId);
            kylinOrderRefundEntities.setRefundPrice(BigDecimal.valueOf(refundPrice));
            kylinOrderRefundEntities.setOrderTicketEntitiesId(orderEntitiesId);
            kylinOrderRefundEntities.setCreatedAt(time);

            KylinOrderRefundEntitiesVo orderRefundEntitiesVo = KylinOrderRefundEntitiesVo.getNew();
            BeanUtils.copyProperties(kylinOrderRefundEntities, orderRefundEntitiesVo);
            orderRefundEntitiesVo.setCreatedAt(strTime);
            mongoTemplate.insert(orderRefundEntitiesVo, KylinOrderRefundEntitiesVo.class.getSimpleName());

            //退款图片
            KylinOrderRefundPic orderRefundPic = new KylinOrderRefundPic();
            orderRefundPic.setRefundPicId(IDGenerator.nextSnowId());
            orderRefundPic.setOrderRefundsId(kylinOrderRefunds.getOrderRefundsId());
            orderRefundPic.setPicUrl(picList);
            orderRefundPic.setCreatedAt(time);

            KylinOrderRefundPicVo orderRefundPicVo = new KylinOrderRefundPicVo();
            BeanUtils.copyProperties(orderRefundPic, orderRefundPicVo);
            orderRefundPicVo.setCreatedAt(strTime);
            mongoTemplate.insert(orderRefundPicVo, KylinOrderRefundPicVo.class.getSimpleName());

            dataUtils.delOrderRefundVoByOrderId(orderInfo.getOrderTicketsId());
            //MQ
            LinkedList<String> sqls = CollectionUtil.linkedListString();
            LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataC = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataD = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsDataE = CollectionUtil.linkedListObjectArr();

            sqls.add(SqlMapping.get("kylin_order_ticket_status.refund"));
            sqls.add(SqlMapping.get("kylin_order_ticket_entities.refund"));
            sqls.add(SqlMapping.get("kylin_order_refund.refund"));
            sqls.add(SqlMapping.get("kylin_order_refund_entities.refund"));
            sqls.add(SqlMapping.get("kylin_order_refund_pic.refund"));

            LocalDateTime now1 = LocalDateTime.now();
            sqlsDataA.add(new Object[]{
                    orderStatusTable.getStatus(), orderStatusTable.getUpdatedAt(), orderInfo.getOrderTicketsId(),now1, now1
            });
            sqlsDataB.add(new Object[]{
                    entitiesTable.getIsPayment(), entitiesTable.getUpdatedAt(), orderEntitiesId,now1, now1
            });
            sqlsDataC.add(new Object[]{
                    kylinOrderRefunds.getOrderRefundsId(), kylinOrderRefunds.getOrderTicketsId(), kylinOrderRefunds.getOrderRefundCode(),
                    kylinOrderRefunds.getPrice(), kylinOrderRefunds.getPriceExpress(), 0, kylinOrderRefunds.getStatus(),
                    kylinOrderRefunds.getType(), kylinOrderRefunds.getApplicantId(), kylinOrderRefunds.getApplicantName(),
                    kylinOrderRefunds.getApplicantAt(), kylinOrderRefunds.getReason(), kylinOrderRefunds.getCreatedAt()
            });
            sqlsDataD.add(new Object[]{
                    kylinOrderRefundEntities.getOrderRefundsEntitiesId(), kylinOrderRefundEntities.getOrderRefundsId(), kylinOrderRefundEntities.getRefundPrice(),
                    kylinOrderRefundEntities.getOrderTicketEntitiesId(), kylinOrderRefundEntities.getCreatedAt()
            });
            sqlsDataE.add(new Object[]{
                    orderRefundPic.getOrderRefundsId(), orderRefundPic.getOrderRefundsId(), orderRefundPic.getPicUrl(), orderRefundPic.getCreatedAt()
            });

            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_ORDER_REFUND.getKey(),
                    SqlMapping.gets(sqls, sqlsDataA, sqlsDataB, sqlsDataC, sqlsDataD, sqlsDataE));

            return kylinOrderRefunds.getOrderRefundsId();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

}
