package com.liquidnet.service.stone.service.impl;

import com.github.pagehelper.PageInfo;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.UserPathDto;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.stone.entity.StoneScoreItems;
import com.liquidnet.service.stone.entity.StoneScoreOrder;
import com.liquidnet.service.stone.service.IStoneScoreOrderService;
import com.liquidnet.service.stone.util.QueueUtils;
import com.liquidnet.service.stone.util.StoneMongoUtils;
import com.liquidnet.service.stone.util.StoneRedisUtils;
import com.liquidnet.service.stone.vo.StoneOrderListVo;
import com.liquidnet.service.stone.vo.StoneScoreItemVo;
import com.liquidnet.service.stone.vo.StoneUserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 积分订单表 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-10-19
 */
@Service
@Slf4j
public class StoneScoreOrderServiceImpl implements IStoneScoreOrderService {

    @Autowired
    StoneRedisUtils stoneRedisUtils;
    @Autowired
    StoneMongoUtils stoneMongoUtils;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    StoneScoreLogsServiceImpl stoneScoreLogsService;

    @Override
    public ResponseDto<String> order(String itemId, Integer number) {
        //判断状态 库存
        String uid = CurrentUtil.getCurrentUid();
        String mCouponId = IDGenerator.nextTimeId2();
        StoneScoreItems data = stoneRedisUtils.getItemData(itemId);
        if (data == null) {
            return ResponseDto.failure("参数异常");
        }
        if (stoneRedisUtils.getStoneGeneralSurplus(itemId) <= 0) {
            return ResponseDto.failure("该商品库存不足");
        }
//        StoneScoreItemVo vo = StoneScoreItemVo.getNew().copy(data, 1, 1);
        StoneUserVo vo = stoneRedisUtils.getUserData(uid);
        if (vo.getStatus() == 2) {
            return ResponseDto.failure("账号被冻结");
        }
        if (data.getStatus() != 1) {
            return ResponseDto.failure("该商品不可下单");
        }
        //获取积分
        int needScore = data.getScore().multiply(BigDecimal.valueOf(number)).intValue();
        if (stoneRedisUtils.getUserScoreRest(uid) < needScore) {
            return ResponseDto.failure("剩余积分不足");
        }
        //获取限购
        int buyCount = stoneRedisUtils.getItemLimit(uid, itemId);
        if ((buyCount + number) > data.getLimitCount() && data.getLimitCount() > 0) {
            return ResponseDto.failure("超出限购数量");
        }
        //增加限购
        stoneRedisUtils.addItemLimit(uid, itemId, number);
        //减少库存
        stoneRedisUtils.changeStoneGeneralSurplus(itemId, -number);
        //减少积分
        stoneScoreLogsService.deScore(uid, needScore, 0, "购买积分商品:" + data.getTargetTitle());
        //下单
        StoneScoreOrder order = StoneScoreOrder.getNew();
        order.setOrderId(IDGenerator.nextTimeId());
        order.setUid(uid);
        Map token = CurrentUtil.getTokenClaims();
        order.setUserName(StringUtils.defaultString(((String) token.get("nickname"))));
        order.setUserMobile(StringUtils.defaultString(((String) token.get("mobile"))));
        order.setItemId(itemId);
        order.setTargetTitle(data.getTargetTitle());
        order.setNumber(number);
        order.setOrderCode(IDGenerator.ticketOrderCode(order.getOrderId()));
        order.setPrice(BigDecimal.ZERO);
        order.setScore(BigDecimal.valueOf(needScore));
        order.setPriceExpress(BigDecimal.ZERO);
        order.setPriceActual(BigDecimal.ZERO);
        order.setPayType("SCORE");
        order.setPaymentType("SCORE");
        order.setPaymentId("");
        order.setTimePay("");
        order.setPayCountdownMinute(0);
        order.setStatus(1);
        order.setPayStatus(1);
        order.setCreatedAt(LocalDateTime.now());
        //redis
        StoneOrderListVo listVo = StoneOrderListVo.getNew().copy(order, data.getImg(), uid);
        stoneRedisUtils.setOrderDetails(listVo.getOrderId(), listVo);
        stoneRedisUtils.addOrderList(uid, listVo);
        //mongo
        stoneMongoUtils.orderCreate(listVo);
        //mysql 订单创建
        LinkedList<String> sqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> sqlsDataA = CollectionUtil.linkedListObjectArr();
        sqls.add(SqlMapping.get("stone_score_order.insert"));
        sqlsDataA.add(new Object[]{
                order.getOrderId(), order.getUid(), order.getUserName(), order.getUserMobile(),
                order.getItemId(), order.getTargetTitle(), order.getOrderCode(), order.getNumber(), order.getPrice(),
                order.getScore(), order.getPriceExpress(), order.getPriceActual(), order.getPayType(), order.getPaymentType(),
                order.getPaymentId(), order.getTimePay(), order.getPayCountdownMinute(), order.getStatus(), 1, order.getCreatedAt(),
                mCouponId
        });
        //mysql 发送券
        LinkedList<Object[]> sqlsDataB = CollectionUtil.linkedListObjectArr();
        sqls.add(SqlMapping.get("stone_candy_mgt_coupon.add_for_member"));
        sqlsDataB.add(new Object[]{
                mCouponId, data.getTargetId(), number, order.getUserMobile(), order.getCreatedAt(), "SCORE_BUY_COUPON", order.getCreatedAt()
        });
        // 执行sql
        String sqlData = SqlMapping.gets(sqls, sqlsDataA, sqlsDataB);
        queueUtils.sendMsgByRedis(MQConst.StoneQueue.STONE_ORDER_COUPON.getKey(),
                sqlData);

        return ResponseDto.success("下单成功");
    }

    @Override
    public PageInfo<List<StoneOrderListVo>> orderList(Integer page) {
        String uid = CurrentUtil.getCurrentUid();
        PageInfo<List<StoneOrderListVo>> mPageInfo;
        int size = 40;
        if (page == null || page == 1 || page == 0) {
            page = 1;
        }
        List<StoneOrderListVo> voList;
        long count;
        if (page == 1) {
            voList = stoneRedisUtils.getOrderList(uid);
            count = voList.size();
        } else {
            HashMap<String, Object> info = stoneMongoUtils.orderList(uid, page, size);
            try {
                voList = (List<StoneOrderListVo>) info.get("total");
                count = (long) info.get("data");
            } catch (Exception e) {
                voList = new ArrayList();
                count = 0;
            }
        }
        mPageInfo = new PageInfo(voList);
        mPageInfo.setTotal(count);
        log.info(UserPathDto.setData("积分订单列表", "", voList));
        return mPageInfo;
    }
}
