package com.liquidnet.service.goblin.service.impl;

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.param.GoblinNowOrderListParam;
import com.liquidnet.service.goblin.service.IGoblinOrderAppService;
import com.liquidnet.service.goblin.service.IGoblinStoreZhengzaiService;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.ObjectUtil;
import com.liquidnet.service.goblin.util.QueueUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

import static com.liquidnet.commons.lang.util.DateUtil.DTF_YMD_HMS;

@Service
public class GoblinStoreZhengzaiServiceImpl implements IGoblinStoreZhengzaiService {

    @Autowired
    GoblinRedisUtils redisUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    IGoblinOrderAppService goblinOrderAppService;


    @Override
    public ResponseDto<List<GoblinSelfMarketingVo>> getZhengzaiMarketList() {
        String uid = CurrentUtil.getCurrentUid();
        GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVoByUid(uid);
        if (storeInfoVo == null) {
            return ResponseDto.failure("店铺不存在");
        }
        String storeId = storeInfoVo.getStoreId();
        List<String> marketIds = redisUtils.getStoreZhengzaiRelation(storeId);//可参加的正在活动id
        List<GoblinSelfMarketingVo> list = redisUtils.getGoblinSelfMarketingVoList();//所有正在下单活动列表
        List<GoblinSelfMarketingVo> voList = ObjectUtil.getGoblinSelfMarketingVoList();
        LocalDateTime now = LocalDateTime.now();
        for (GoblinSelfMarketingVo item : list) {
            GoblinMarketingZhengzaiRelationVo zhengzaiRelationVo = redisUtils.getZhengzaiRelation(item.getSelfMarketId(), storeId);
            if (LocalDateTime.parse(item.getEndTime(), DTF_YMD_HMS).isAfter(now) && zhengzaiRelationVo != null) {
                if (marketIds.contains(item.getSelfMarketId())) {
                    List<GoblinMarketRelationVo> relationVo = redisUtils.getMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), item.getSelfMarketId());
                    List<String> storeIdList = relationVo.stream().map(GoblinMarketRelationVo::getStoreId).distinct().collect(Collectors.toList());//配置了商铺的店铺
                    if (storeIdList.contains(storeId)) {
                        voList.add(item);
                    }
                }
            }
        }
        return ResponseDto.success(voList);
    }

    @Override
    public ResponseDto<List<GoblinZhengzaiGoodVo>> getSpuList(String marketId, String keyword) {
        String uid = CurrentUtil.getCurrentUid();
        GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVoByUid(uid);
        if (storeInfoVo == null) {
            return ResponseDto.failure("店铺不存在");
        }
        GoblinSelfMarketingVo marketingVo = redisUtils.getSelfMarket(marketId);
        if (marketingVo.getStatus() != null && marketingVo.getStatus() == 7) {
            return ResponseDto.failure("活动已停用");
        }
        //todo
        String storeId = storeInfoVo.getStoreId();
        GoblinMarketingZhengzaiRelationVo marketingZhengzaiRelationVo = redisUtils.getZhengzaiRelation(marketId, storeId);
        if (marketingZhengzaiRelationVo == null) {
            return ResponseDto.failure("未参加活动");
        }
        List<GoblinMarketRelationVo> relationVo = redisUtils.getMarketRelation(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), marketId);
        List<String> spuIdList = relationVo.stream().map(GoblinMarketRelationVo::getSpuId).collect(Collectors.toList());

        // 支持搜索SPU
        boolean toSearchFlg = StringUtils.isNotBlank(keyword);
        List<String> hitSpuIdList = toSearchFlg ? mongoUtils.getSpuIdListBySpuIdListAndKeyword(spuIdList, keyword) : null;

        List<GoblinZhengzaiGoodVo> voList = ObjectUtil.getGoblinZhengzaiGoodVoArrayList();
        if (toSearchFlg && CollectionUtils.isEmpty(hitSpuIdList)) {
            return ResponseDto.success(voList);
        }
        for (String spuId : spuIdList) {
            GoblinGoodsInfoVo vo = !toSearchFlg || hitSpuIdList.contains(spuId) ? redisUtils.getGoodsInfoVo(spuId) : null;
            if (null != vo && vo.getShelvesStatus().equals("3") && vo.getStoreId().equals(storeId)) {
                GoblinZhengzaiGoodVo returnVo = GoblinZhengzaiGoodVo.getNew();
                vo.setMarketId(vo.getMarketId().replace(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), ""));
                BeanUtils.copyProperties(vo, returnVo);
                voList.add(returnVo);
            }
        }
        return ResponseDto.success(voList);
    }

    @Override
    public ResponseDto<GoblinZhengzaiGoodPageVo> getSpuList2(String marketId, String keyword, Integer page) {
        String uid = CurrentUtil.getCurrentUid();
        GoblinZhengzaiGoodPageVo goodPageVo = GoblinZhengzaiGoodPageVo.getNew();
        GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVoByUid(uid);
        if (storeInfoVo == null) {
            return ResponseDto.failure("店铺不存在");
        }
        GoblinSelfMarketingVo marketingVo = redisUtils.getSelfMarket(marketId);
        if (marketingVo.getStatus() != null && marketingVo.getStatus() == 7) {
            return ResponseDto.failure("活动已停用");
        }
        //todo
        String storeId = storeInfoVo.getStoreId();
        GoblinMarketingZhengzaiRelationVo marketingZhengzaiRelationVo = redisUtils.getZhengzaiRelation(marketId, storeId);
        if (marketingZhengzaiRelationVo == null) {
            return ResponseDto.failure("未参加活动");
        }

        // 支持搜索SPU
        HashMap map = mongoUtils.getMarketSpuData(marketId, page, keyword, storeId);
        long total = (long) map.get("total");
        List<String> hitSpuIdList = (List<String>) map.get("data");

        List<GoblinZhengzaiGoodVo> voList = ObjectUtil.getGoblinZhengzaiGoodVoArrayList();
        for (String spuId : hitSpuIdList) {
            GoblinGoodsInfoVo vo = hitSpuIdList.contains(spuId) ? redisUtils.getGoodsInfoVo(spuId) : null;
            if (null != vo && vo.getShelvesStatus().equals("3")) {
                GoblinZhengzaiGoodVo returnVo = GoblinZhengzaiGoodVo.getNew();
                vo.setMarketId(vo.getMarketId().replace(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue(), ""));
                BeanUtils.copyProperties(vo, returnVo);
                voList.add(returnVo);
            }
        }
        goodPageVo.setData(voList);
        goodPageVo.setPage(page);
        goodPageVo.setTotal(total);
        return ResponseDto.success(goodPageVo);
    }

    @Override
    public ResponseDto<List<GoblinAppOrderListVo>> orderList(int page) {
        String uid = CurrentUtil.getCurrentUid();
        List<GoblinAppOrderListVo> orderVoList = ObjectUtil.goblinAppOrderListVoArrayList();
        GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVoByUid(uid);
        List<GoblinStoreOrderVo> mongoVoList = mongoUtils.storeZhengzaiOrderList(page, storeInfoVo.getStoreId());
        for (GoblinStoreOrderVo orderVo : mongoVoList) {
            GoblinAppOrderListVo vo = GoblinAppOrderListVo.getNew();
            BeanUtils.copyProperties(orderVo, vo);
            vo.setRestTime(getRestTime(orderVo));
            List<GoblinOrderSkuVo> skuVos = ObjectUtil.getGoblinOrderSkuVoArrayList();
            for (String orderSkuId : orderVo.getOrderSkuVoIds()) {
                GoblinOrderSkuVo orderSkuVo = redisUtils.getGoblinOrderSkuVo(orderSkuId);
                skuVos.add(orderSkuVo);
            }
            vo.setOrderSkuVos(skuVos);
            orderVoList.add(vo);
        }
        return ResponseDto.success(orderVoList);
    }

    @Override
    public ResponseDto<Boolean> orderPush(String orderMasterCode) {
        String[] orderIds = redisUtils.getMasterCode(orderMasterCode);
        LocalDateTime now = LocalDateTime.now();
        LinkedList<Object[]> sqlDataOrder = CollectionUtil.linkedListObjectArr();
        if (orderIds == null) {
            return ResponseDto.failure("订单不存在");
        } else {
            for (String orderId : orderIds) {
                GoblinStoreOrderVo storeOrderVo = redisUtils.getGoblinOrder(orderId);
                storeOrderVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_4.getValue());
                storeOrderVo.setZhengzaiStatus(1);
                //mongo
                mongoUtils.updateGoblinStoreOrderVo(storeOrderVo.getOrderId(), storeOrderVo);
                //redis
                redisUtils.setGoblinOrder(storeOrderVo.getOrderId(), storeOrderVo);
                sqlDataOrder.add(new Object[]{
                        storeOrderVo.getZhengzaiStatus(), storeOrderVo.getStatus(), now, storeOrderVo.getOrderId(), now, now
                });
            }
            //mysql
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_STORE_ORDER_OPERA.getKey(),
                    SqlMapping.get("goblin_order.zhengzai.push", sqlDataOrder));
        }
        return ResponseDto.success();
    }

    @Override
    public ResponseDto<List<GoblinNowOrderListVo>> nowOrderList(GoblinNowOrderListParam param) {
        String storeId = param.getStoreId();
        String marketId = param.getMarketId();
        int page = param.getPage();
        String orderCode = param.getOrderCode();
        List<GoblinNowOrderListVo> data = mongoUtils.getGoblinNowOrderListVo(orderCode, storeId, marketId, page);
        return ResponseDto.success(data);
    }

    @Override
    public ResponseDto<GoblinAppOrderDetailsVo> nowOrderDetails(GoblinNowOrderListParam param) {
        String storeId = param.getStoreId();
        String marketId = param.getMarketId();
        String orderCode = param.getOrderCode();
        GoblinNowOrderListVo data = mongoUtils.getGoblinNowOrderDetailsVo(orderCode, storeId, marketId);
        if (data == null) {
            return ResponseDto.failure("订单不存在");
        }
        ResponseDto<GoblinAppOrderDetailsVo> responseVo = goblinOrderAppService.orderDetails(data.getOrderId(), data.getUserId());
        return ResponseDto.success(responseVo.getData());
    }

    //获取 订单剩余可支付时间[S]
    private long getRestTime(GoblinStoreOrderVo orderVo) {
        long restTime = 0L;
        if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_0.getValue()) {
            try {
                Date OverdueAt = DateUtil.addMin(DateUtil.parse(orderVo.getCreatedAt(), "yyyy-MM-dd HH:mm:ss"), orderVo.getPayCountdownMinute());
                restTime = DateUtil.intervalSeconds(
                        OverdueAt,
                        DateUtil.parse(DateUtil.getNowTime(), "yyyy-MM-dd HH:mm:ss")
                );
                if (restTime <= 0L) {
                    restTime = 0L;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return restTime;
    }
}
