package com.liquidnet.service.order.utils;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.base.constant.RedisKeyExpireConst;
import com.liquidnet.service.kylin.constant.GroupBuyStatusConst;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.param.PayOrderParam;
import com.liquidnet.service.kylin.dto.vo.groupbuy.KylinGroupBuyActivityVo;
import com.liquidnet.service.kylin.dto.vo.groupbuy.KylinGroupBuyDiscountVo;
import com.liquidnet.service.kylin.dto.vo.groupbuy.KylinGroupBuyMemberVo;
import com.liquidnet.service.kylin.dto.vo.groupbuy.KylinGroupBuyOrderVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 拼团下单/支付确认辅助：写 Mongo+Redis，MySQL 走 MQ。
 */
@Component
@Slf4j
public class GroupBuyOrderHelper {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private QueueUtils queueUtils;
    @Autowired
    private GroupBuySmsSender groupBuySmsSender;

    public boolean isGroupBuyOrder(PayOrderParam param) {
        return param != null && (StringUtils.isNotBlank(param.getGroupBuyActivityId())
                || StringUtils.isNotBlank(param.getGroupOrderId()));
    }

    /**
     * 库存前校验：禁券 + 发起/加入校验。失败返回 failure。
     */
    public ResponseDto<Boolean> validateBeforeOrder(PayOrderParam param, String uid) {
        if (!isGroupBuyOrder(param)) {
            return ResponseDto.success(true);
        }
        if (StringUtils.isNotBlank(param.getVoucherCode())
                || StringUtils.isNotBlank(param.getAdvanceCode())
                || (param.getVoucherType() != null && param.getVoucherType().equals(3))) {
            return ResponseDto.failure("拼团订单不支持优惠券/兑换券/优先购券");
        }
        if (StringUtils.isNotBlank(param.getGroupBuyActivityId()) && StringUtils.isNotBlank(param.getGroupOrderId())) {
            return ResponseDto.failure("发起与加入参数不能同时传");
        }
        if (StringUtils.isNotBlank(param.getGroupBuyActivityId())) {
            return validateCreate(param, uid);
        }
        return validateJoin(param, uid);
    }

    /**
     * 再次支付前置校验：票单已绑定团，只判断能否继续付，不重建团。
     * 非拼团票单直接通过。
     */
    public ResponseDto<Boolean> validateBeforePayAgain(KylinOrderTicketVo ticket, String uid) {
        if (ticket == null || StringUtils.isBlank(ticket.getGroupOrderId())) {
            return ResponseDto.success(true);
        }
        KylinGroupBuyOrderVo group = findGroup(ticket.getGroupOrderId());
        if (group == null) {
            return ResponseDto.failure("拼团不存在");
        }
        KylinGroupBuyMemberVo member = findMember(group, ticket.getOrderTicketsId());
        if (member == null) {
            return ResponseDto.failure("拼团成员不存在");
        }
        if (!GroupBuyStatusConst.MemberStatus.PENDING_PAY.equals(member.getStatus())) {
            return ResponseDto.failure("拼团成员状态不可支付");
        }
        Integer groupStatus = group.getStatus();
        if (GroupBuyStatusConst.OrderStatus.CANCELLED.equals(groupStatus)) {
            return ResponseDto.failure("拼团已取消，无法支付");
        }
        if (GroupBuyStatusConst.OrderStatus.FAILED.equals(groupStatus)) {
            return ResponseDto.failure("拼团已失败，无法支付");
        }
        if (GroupBuyStatusConst.OrderStatus.SUCCESS.equals(groupStatus)) {
            return ResponseDto.failure("拼团已结束，无法支付");
        }
        if (GroupBuyStatusConst.OrderStatus.PREPARE.equals(groupStatus)) {
            if (!uid.equals(group.getLeaderUserId()) || !uid.equals(member.getUserId())) {
                return ResponseDto.failure("拼团当前不可支付");
            }
            return ResponseDto.success(true);
        }
        if (GroupBuyStatusConst.OrderStatus.PENDING.equals(groupStatus)) {
            if (group.getExpiresAt() != null
                    && DateUtil.Formatter.yyyyMMddHHmmss.parse(group.getExpiresAt()).isBefore(LocalDateTime.now())) {
                return ResponseDto.failure("拼团已过期");
            }
            return ResponseDto.success(true);
        }
        return ResponseDto.failure("拼团当前不可支付");
    }

    private ResponseDto<Boolean> validateCreate(PayOrderParam param, String uid) {
        KylinGroupBuyActivityVo activity = getActiveActivity(param.getGroupBuyActivityId());
        if (activity == null) {
            return ResponseDto.failure("拼团活动不存在或未进行中");
        }
        if (!activity.getPerformanceId().equals(param.getPerformanceId())) {
            return ResponseDto.failure("演出与拼团活动不匹配");
        }
        KylinGroupBuyDiscountVo discount = findDiscount(activity, param.getTimeId(), param.getTicketId());
        if (discount == null) {
            return ResponseDto.failure("该票档不支持拼团");
        }
        if (param.getNumber() == null || param.getNumber() < 1
                || param.getNumber() > activity.getMaxBuyPerUser()) {
            return ResponseDto.failure("超过拼团限购数量");
        }
        Query exists = Query.query(Criteria.where("activityId").is(param.getGroupBuyActivityId())
                .and("leaderUserId").is(uid)
                .and("status").in(GroupBuyStatusConst.OrderStatus.PREPARE, GroupBuyStatusConst.OrderStatus.PENDING));
        if (mongoTemplate.exists(exists, KylinGroupBuyOrderVo.class, KylinGroupBuyOrderVo.class.getSimpleName())) {
            return ResponseDto.failure("同一活动只能发起一次拼团");
        }
        return ResponseDto.success(true);
    }

    private ResponseDto<Boolean> validateJoin(PayOrderParam param, String uid) {
        KylinGroupBuyOrderVo group = findGroup(param.getGroupOrderId());
        if (group == null) {
            return ResponseDto.failure("拼团不存在");
        }
        if (!GroupBuyStatusConst.OrderStatus.PENDING.equals(group.getStatus())) {
            return ResponseDto.failure("拼团当前不可加入");
        }
        if (group.getExpiresAt() != null
                && DateUtil.Formatter.yyyyMMddHHmmss.parse(group.getExpiresAt()).isBefore(LocalDateTime.now())) {
            return ResponseDto.failure("拼团已过期");
        }
        if (group.getCurrentCount() != null && group.getTargetCount() != null
                && group.getCurrentCount() >= group.getTargetCount()) {
            return ResponseDto.failure("拼团人数已满");
        }
        if (GroupBuyStatusConst.PublicFlag.PRIVATE.equals(group.getIsPublic())) {
            if (StringUtils.isBlank(param.getShareToken()) || !param.getShareToken().equals(group.getShareToken())) {
                return ResponseDto.failure("邀请链接无效");
            }
        }
        if (!param.getTimeId().equals(group.getTimeId()) || !param.getTicketId().equals(group.getTicketId())) {
            return ResponseDto.failure("场次或票档与拼团不一致");
        }
        KylinGroupBuyActivityVo activity = getActiveActivity(group.getActivityId());
        if (activity == null) {
            return ResponseDto.failure("拼团活动已结束");
        }
        if (param.getNumber() == null || param.getNumber() < 1
                || param.getNumber() > activity.getMaxBuyPerUser()) {
            return ResponseDto.failure("超过拼团限购数量");
        }
        if (!CollectionUtils.isEmpty(group.getMembers())) {
            for (KylinGroupBuyMemberVo m : group.getMembers()) {
                if (uid.equals(m.getUserId())
                        && (GroupBuyStatusConst.MemberStatus.PENDING_PAY.equals(m.getStatus())
                        || GroupBuyStatusConst.MemberStatus.JOINED.equals(m.getStatus()))) {
                    return ResponseDto.failure("您已在该拼团中");
                }
            }
        }
        return ResponseDto.success(true);
    }

    /**
     * 拼团单价；非拼团返回 null。
     */
    public BigDecimal resolveUnitPrice(PayOrderParam param, BigDecimal originalPrice) {
        if (!isGroupBuyOrder(param) || originalPrice == null) {
            return null;
        }
        KylinGroupBuyActivityVo activity;
        if (StringUtils.isNotBlank(param.getGroupBuyActivityId())) {
            activity = getActiveActivity(param.getGroupBuyActivityId());
        } else {
            KylinGroupBuyOrderVo group = findGroup(param.getGroupOrderId());
            activity = group == null ? null : getActiveActivity(group.getActivityId());
        }
        if (activity == null) {
            return null;
        }
        KylinGroupBuyDiscountVo discount = findDiscount(activity, param.getTimeId(), param.getTicketId());
        if (discount == null) {
            return null;
        }
        return calculatePrice(originalPrice, discount);
    }

    public BigDecimal calculatePrice(BigDecimal originalPrice, KylinGroupBuyDiscountVo discount) {
        if (originalPrice == null || discount == null || discount.getDiscountValue() == null) {
            return null;
        }
        BigDecimal value = discount.getDiscountValue();
        if (GroupBuyStatusConst.DiscountType.FIXED_PRICE.equals(discount.getDiscountType())) {
            return value.max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        }
        if (GroupBuyStatusConst.DiscountType.DISCOUNT.equals(discount.getDiscountType())) {
            return originalPrice.multiply(value).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)
                    .max(BigDecimal.ZERO);
        }
        if (GroupBuyStatusConst.DiscountType.REDUCE.equals(discount.getDiscountType())) {
            return originalPrice.subtract(value).max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
        }
        return null;
    }

    /**
     * 下单成功后写团 + member(-1)，回填 ticket.groupOrderId，发 MQ。
     */
    public String createOrJoinOnOrder(PayOrderParam param, String uid, String orderTicketsId,
                                      Integer ticketCount, String nickname, String avatar) {
        if (!isGroupBuyOrder(param)) {
            return null;
        }
        String now = now();
        if (StringUtils.isNotBlank(param.getGroupBuyActivityId())) {
            return createPrepareGroup(param, uid, orderTicketsId, ticketCount, nickname, avatar, now);
        }
        return joinPendingGroup(param, uid, orderTicketsId, ticketCount, nickname, avatar, now);
    }

    private String createPrepareGroup(PayOrderParam param, String uid, String orderTicketsId,
                                      Integer ticketCount, String nickname, String avatar, String now) {
        KylinGroupBuyActivityVo activity = getActiveActivity(param.getGroupBuyActivityId());
        if (activity == null) {
            throw new IllegalStateException("拼团活动不存在或未进行中");
        }
        String groupOrderId = IDGenerator.nextSnowId();
        KylinGroupBuyMemberVo member = buildMember(groupOrderId, uid, orderTicketsId, ticketCount,
                nickname, avatar, now);
        KylinGroupBuyOrderVo group = new KylinGroupBuyOrderVo();
        group.setGroupOrderId(groupOrderId);
        group.setActivityId(activity.getActivityId());
        group.setLeaderUserId(uid);
        group.setOrderTicketsId(orderTicketsId);
        group.setTimeId(param.getTimeId());
        group.setTicketId(param.getTicketId());
        group.setTargetCount(activity.getMinGroupSize());
        group.setCurrentCount(1);
        group.setStatus(GroupBuyStatusConst.OrderStatus.PREPARE);
        group.setIsPublic(param.getIsPublic() == null ? GroupBuyStatusConst.PublicFlag.PUBLIC : param.getIsPublic());
        group.setShareToken(IDGenerator.nextSnowId());
        group.setCreatedAt(now);
        group.setUpdatedAt(now);
        List<KylinGroupBuyMemberVo> members = new ArrayList<>();
        members.add(member);
        group.setMembers(members);

        mongoTemplate.insert(group, KylinGroupBuyOrderVo.class.getSimpleName());
        cacheGroup(group);
        sendReplaceGroupSql(group);
        return groupOrderId;
    }

    private String joinPendingGroup(PayOrderParam param, String uid, String orderTicketsId,
                                    Integer ticketCount, String nickname, String avatar, String now) {
        String groupOrderId = param.getGroupOrderId();
        String lockKey = KylinRedisConst.GROUP_BUY_ORDER_LOCK.concat(groupOrderId);
        if (!redisUtil.lock(lockKey, 1, 15)) {
            throw new IllegalStateException("拼团火爆，请稍后重试");
        }
        try {
            // 持锁后回源 Mongo，避免并发读到脏缓存
            KylinGroupBuyOrderVo group = loadGroupFromMongo(groupOrderId);
            if (group == null || !GroupBuyStatusConst.OrderStatus.PENDING.equals(group.getStatus())) {
                throw new IllegalStateException("拼团当前不可加入");
            }
            if (group.getExpiresAt() != null
                    && DateUtil.Formatter.yyyyMMddHHmmss.parse(group.getExpiresAt()).isBefore(LocalDateTime.now())) {
                throw new IllegalStateException("拼团已过期");
            }
            if (group.getCurrentCount() != null && group.getTargetCount() != null
                    && group.getCurrentCount() >= group.getTargetCount()) {
                throw new IllegalStateException("拼团人数已满");
            }
            if (GroupBuyStatusConst.PublicFlag.PRIVATE.equals(group.getIsPublic())) {
                if (StringUtils.isBlank(param.getShareToken()) || !param.getShareToken().equals(group.getShareToken())) {
                    throw new IllegalStateException("邀请链接无效");
                }
            }
            if (!CollectionUtils.isEmpty(group.getMembers())) {
                for (KylinGroupBuyMemberVo m : group.getMembers()) {
                    if (uid.equals(m.getUserId())
                            && (GroupBuyStatusConst.MemberStatus.PENDING_PAY.equals(m.getStatus())
                            || GroupBuyStatusConst.MemberStatus.JOINED.equals(m.getStatus()))) {
                        throw new IllegalStateException("您已在该拼团中");
                    }
                }
            } else {
                group.setMembers(new ArrayList<>());
            }
            KylinGroupBuyMemberVo member = buildMember(group.getGroupOrderId(), uid, orderTicketsId, ticketCount,
                    nickname, avatar, now);
            group.getMembers().add(member);
            group.setCurrentCount((group.getCurrentCount() == null ? 0 : group.getCurrentCount()) + 1);
            group.setUpdatedAt(now);
            saveGroup(group);
            return group.getGroupOrderId();
        } finally {
            redisUtil.uLock(lockKey);
        }
    }

    private KylinGroupBuyOrderVo loadGroupFromMongo(String groupOrderId) {
        if (StringUtils.isBlank(groupOrderId)) {
            return null;
        }
        return mongoTemplate.findOne(
                Query.query(Criteria.where("groupOrderId").is(groupOrderId)),
                KylinGroupBuyOrderVo.class, KylinGroupBuyOrderVo.class.getSimpleName());
    }

    /**
     * 支付成功：按 orderTicketsId 确认成员；团长则开团；满员则成团。
     * @return 0无拼团 1成功 2需退款
     */
    public int confirmPaidMember(KylinOrderTicketVo ticket) {
        if (ticket == null || StringUtil.isEmpty(ticket.getOrderTicketsId())) {
            return 0;
        }
        KylinGroupBuyOrderVo located = findGroupByOrderTicketsId(ticket.getOrderTicketsId());
        if (located == null) {
            return 0;
        }
        String lockKey = KylinRedisConst.GROUP_BUY_ORDER_LOCK.concat(located.getGroupOrderId());
        if (!redisUtil.lock(lockKey, 1, 15)) {
            log.warn("拼团支付确认获取锁失败 groupOrderId={}", located.getGroupOrderId());
            return 0;
        }
        try {
            KylinGroupBuyOrderVo group = loadGroupFromMongo(located.getGroupOrderId());
            if (group == null) {
                return 0;
            }
            KylinGroupBuyMemberVo member = findMember(group, ticket.getOrderTicketsId());
            if (member == null) {
                return 0;
            }
            if (GroupBuyStatusConst.MemberStatus.JOINED.equals(member.getStatus())) {
                return 1;
            }
            Integer groupStatus = group.getStatus();
            String now = now();
            if (GroupBuyStatusConst.OrderStatus.CANCELLED.equals(groupStatus)
                    || GroupBuyStatusConst.OrderStatus.FAILED.equals(groupStatus)
                    || (GroupBuyStatusConst.OrderStatus.SUCCESS.equals(groupStatus)
                    && GroupBuyStatusConst.MemberStatus.PENDING_PAY.equals(member.getStatus()))) {
                member.setStatus(GroupBuyStatusConst.MemberStatus.REFUNDED);
                if (group.getCurrentCount() != null && group.getCurrentCount() > 0) {
                    group.setCurrentCount(group.getCurrentCount() - 1);
                }
                group.setUpdatedAt(now);
                saveGroup(group);
                return 2;
            }
            if (GroupBuyStatusConst.OrderStatus.PREPARE.equals(groupStatus)
                    && ticket.getUserId().equals(group.getLeaderUserId())) {
                group.setStatus(GroupBuyStatusConst.OrderStatus.PENDING);
                group.setExpiresAt(DateUtil.Formatter.yyyyMMddHHmmss.format(LocalDateTime.now().plusHours(24)));
                member.setStatus(GroupBuyStatusConst.MemberStatus.JOINED);
                group.setUpdatedAt(now);
                saveGroup(group);
                return 1;
            }
            if (GroupBuyStatusConst.OrderStatus.PENDING.equals(groupStatus)) {
                member.setStatus(GroupBuyStatusConst.MemberStatus.JOINED);
                boolean becameSuccess = false;
                if (group.getCurrentCount() != null && group.getTargetCount() != null
                        && group.getCurrentCount() >= group.getTargetCount()) {
                    group.setStatus(GroupBuyStatusConst.OrderStatus.SUCCESS);
                    becameSuccess = true;
                }
                group.setUpdatedAt(now);
                saveGroup(group);
                if (becameSuccess) {
                    try {
                        groupBuySmsSender.notifySuccess(group);
                    } catch (Exception e) {
                        log.error("拼团成功短信通知失败 groupOrderId={}", group.getGroupOrderId(), e);
                    }
                }
                return 1;
            }
            return 0;
        } finally {
            redisUtil.uLock(lockKey);
        }
    }

    public KylinGroupBuyActivityVo getActiveActivity(String activityId) {
        if (activityId == null) {
            return null;
        }
        Object obj = redisUtil.get(KylinRedisConst.GROUP_BUY_ACTIVITY.concat(activityId));
        if (obj != null) {
            KylinGroupBuyActivityVo activity = (KylinGroupBuyActivityVo) obj;
            return GroupBuyStatusConst.ActivityStatus.ACTIVE.equals(activity.getStatus()) ? activity : null;
        }
        KylinGroupBuyActivityVo activity = mongoTemplate.findOne(
                Query.query(Criteria.where("activityId").is(activityId)
                        .and("status").is(GroupBuyStatusConst.ActivityStatus.ACTIVE)),
                KylinGroupBuyActivityVo.class, KylinGroupBuyActivityVo.class.getSimpleName());
        if (activity != null) {
            redisUtil.set(KylinRedisConst.GROUP_BUY_ACTIVITY.concat(activityId), activity,
                    RedisKeyExpireConst.KYLIN_GROUP_BUY_EXPIRE);
        }
        return activity;
    }

    public KylinGroupBuyDiscountVo findDiscount(KylinGroupBuyActivityVo activity, String timeId, String ticketId) {
        if (activity == null || activity.getDiscounts() == null) {
            return null;
        }
        for (KylinGroupBuyDiscountVo discount : activity.getDiscounts()) {
            if (timeId.equals(discount.getTimeId()) && ticketId.equals(discount.getTicketId())) {
                return discount;
            }
        }
        return null;
    }

    public KylinGroupBuyOrderVo findGroup(String groupOrderId) {
        if (StringUtils.isBlank(groupOrderId)) {
            return null;
        }
        Object obj = redisUtil.get(KylinRedisConst.GROUP_BUY_ORDER.concat(groupOrderId));
        if (obj != null) {
            return (KylinGroupBuyOrderVo) obj;
        }
        KylinGroupBuyOrderVo group = mongoTemplate.findOne(
                Query.query(Criteria.where("groupOrderId").is(groupOrderId)),
                KylinGroupBuyOrderVo.class, KylinGroupBuyOrderVo.class.getSimpleName());
        cacheGroup(group);
        return group;
    }

    public KylinGroupBuyOrderVo findGroupByOrderTicketsId(String orderTicketsId) {
        KylinGroupBuyOrderVo group = mongoTemplate.findOne(
                Query.query(Criteria.where("members.orderTicketsId").is(orderTicketsId)),
                KylinGroupBuyOrderVo.class, KylinGroupBuyOrderVo.class.getSimpleName());
        if (group != null) {
            cacheGroup(group);
        }
        return group;
    }

    private KylinGroupBuyMemberVo findMember(KylinGroupBuyOrderVo group, String orderTicketsId) {
        if (group == null || CollectionUtils.isEmpty(group.getMembers())) {
            return null;
        }
        for (KylinGroupBuyMemberVo m : group.getMembers()) {
            if (orderTicketsId.equals(m.getOrderTicketsId())) {
                return m;
            }
        }
        return null;
    }

    private KylinGroupBuyMemberVo buildMember(String groupOrderId, String uid, String orderTicketsId,
                                              Integer ticketCount, String nickname, String avatar, String now) {
        KylinGroupBuyMemberVo member = new KylinGroupBuyMemberVo();
        member.setMemberId(IDGenerator.nextSnowId());
        member.setGroupOrderId(groupOrderId);
        member.setUserId(uid);
        member.setOrderTicketsId(orderTicketsId);
        member.setTicketCount(ticketCount);
        member.setStatus(GroupBuyStatusConst.MemberStatus.PENDING_PAY);
        member.setJoinTime(now);
        member.setCreatedAt(now);
        member.setNickname(nickname == null ? "" : nickname);
        member.setAvatar(avatar == null ? "" : avatar);
        return member;
    }

    private void saveGroup(KylinGroupBuyOrderVo group) {
        clearGroupCache(group);
        mongoTemplate.remove(Query.query(Criteria.where("groupOrderId").is(group.getGroupOrderId())),
                KylinGroupBuyOrderVo.class, KylinGroupBuyOrderVo.class.getSimpleName());
        mongoTemplate.insert(group, KylinGroupBuyOrderVo.class.getSimpleName());
        cacheGroup(group);
        sendReplaceGroupSql(group);
    }

    private void cacheGroup(KylinGroupBuyOrderVo group) {
        if (group == null) {
            return;
        }
        redisUtil.set(KylinRedisConst.GROUP_BUY_ORDER.concat(group.getGroupOrderId()), group,
                RedisKeyExpireConst.KYLIN_GROUP_BUY_EXPIRE);
        if (StringUtils.isNotBlank(group.getShareToken())) {
            redisUtil.set(KylinRedisConst.GROUP_BUY_ORDER_SHARE.concat(group.getShareToken()), group,
                    RedisKeyExpireConst.KYLIN_GROUP_BUY_EXPIRE);
        }
    }

    private void clearGroupCache(KylinGroupBuyOrderVo group) {
        if (group == null) {
            return;
        }
        redisUtil.del(KylinRedisConst.GROUP_BUY_ORDER.concat(group.getGroupOrderId()));
        if (StringUtils.isNotBlank(group.getShareToken())) {
            redisUtil.del(KylinRedisConst.GROUP_BUY_ORDER_SHARE.concat(group.getShareToken()));
        }
    }

    private void sendReplaceGroupSql(KylinGroupBuyOrderVo group) {
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> orderDel = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> orderIns = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> memberDel = CollectionUtil.linkedListObjectArr();
        LinkedList<Object[]> memberIns = CollectionUtil.linkedListObjectArr();
        sqls.add(SqlMapping.get("kylin_group_buy_order.delete"));
        orderDel.add(new Object[]{group.getGroupOrderId()});
        sqls.add(SqlMapping.get("kylin_group_buy_order.insert"));
        orderIns.add(orderInsertObject(group));
        sqls.add(SqlMapping.get("kylin_group_buy_member.delete_by_group"));
        memberDel.add(new Object[]{group.getGroupOrderId()});
        if (!CollectionUtils.isEmpty(group.getMembers())) {
            sqls.add(SqlMapping.get("kylin_group_buy_member.insert"));
            for (KylinGroupBuyMemberVo m : group.getMembers()) {
                memberIns.add(memberInsertObject(m));
            }
            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_ORDER_CREATE.getKey(),
                    SqlMapping.gets(sqls, orderDel, orderIns, memberDel, memberIns));
        } else {
            queueUtils.sendMsgByRedis(MQConst.KylinQueue.SQL_ORDER_CREATE.getKey(),
                    SqlMapping.gets(sqls, orderDel, orderIns, memberDel));
        }
    }

    private Object[] orderInsertObject(KylinGroupBuyOrderVo vo) {
        return new Object[]{
                vo.getGroupOrderId(), vo.getActivityId(), vo.getLeaderUserId(), vo.getOrderTicketsId(),
                vo.getTargetCount(), vo.getCurrentCount(), vo.getStatus(), vo.getIsPublic(), vo.getShareToken(),
                vo.getExpiresAt() == null ? null : DateUtil.Formatter.yyyyMMddHHmmss.parse(vo.getExpiresAt()),
                DateUtil.Formatter.yyyyMMddHHmmss.parse(vo.getCreatedAt()),
                DateUtil.Formatter.yyyyMMddHHmmss.parse(vo.getUpdatedAt())
        };
    }

    private Object[] memberInsertObject(KylinGroupBuyMemberVo vo) {
        return new Object[]{
                vo.getMemberId(), vo.getGroupOrderId(), vo.getUserId(), vo.getOrderTicketsId(),
                vo.getTicketCount(), vo.getStatus(),
                DateUtil.Formatter.yyyyMMddHHmmss.parse(vo.getJoinTime()),
                DateUtil.Formatter.yyyyMMddHHmmss.parse(vo.getCreatedAt())
        };
    }

    private String now() {
        return DateUtil.Formatter.yyyyMMddHHmmss.format(LocalDateTime.now());
    }
}
