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

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.adam.dto.vo.AdamUserInfoVo;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.dto.manage.GoblinGoodsAnticipateAddParam;
import com.liquidnet.service.goblin.dto.manage.GoblinGoodsAnticipateValueAddParam;
import com.liquidnet.service.goblin.dto.manage.GoblinGoodsAnticipateValueParam;
import com.liquidnet.service.goblin.dto.manage.vo.AnticipateValueVo;
import com.liquidnet.service.goblin.dto.manage.vo.GoblinGoodsAnticipateValueVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsAnticipateVo;
import com.liquidnet.service.goblin.service.manage.IGoblinGoodsAnticipateMgService;
import com.liquidnet.service.goblin.util.GoblinAnticipateUtils;
import com.liquidnet.service.goblin.util.GoblinMongoUtils;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.QueueUtils;
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.BigInteger;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 * 预约表 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2022-04-07
 */
@Service
@Slf4j
public class GoblinGoodsAnticipateMgServiceImpl implements IGoblinGoodsAnticipateMgService {

    @Autowired
    GoblinMongoUtils goblinMongoUtils;

    @Autowired
    GoblinRedisUtils goblinRedisUtils;

    @Autowired
    QueueUtils queueUtils;

    @Autowired
    GoblinAnticipateUtils goblinAnticipateUtils;

    @Override
    public ResponseDto<String> add(GoblinGoodsAnticipateAddParam goodsAnticipateAddParam) {
        if (StringUtils.isNotBlank(goodsAnticipateAddParam.getRule()) && goodsAnticipateAddParam.getList() != null && goodsAnticipateAddParam.getList().size() > 0) {
            for (GoblinGoodsAnticipateValueAddParam vo : goodsAnticipateAddParam.getList()) {
                if (goblinRedisUtils.getSkuId(vo.getSkuId())) {
                    return ResponseDto.failure(vo.getSkuName().concat("该商品已创建预约！"));
                }
                if (vo.getAboutStartDate().isAfter(vo.getAboutEndDate())) {
                    return ResponseDto.failure(vo.getSkuName().concat("该商品预约时间在结束时间之后，不可创建！"));
                }
            }

            for (GoblinGoodsAnticipateValueAddParam goodsAnticipateValueAddParam : goodsAnticipateAddParam.getList()) {
                //生成的antId
                String antId = IDGenerator.nextTimeId2();
//                GoblinGoodsAnticipateVo goodsAnticipateVo = new GoblinGoodsAnticipateVo();
                GoblinGoodsAnticipateVo goodsAnticipateVo = GoblinGoodsAnticipateVo.getNew();
                goodsAnticipateVo.copy(goodsAnticipateAddParam);
                goodsAnticipateVo.setAntId(antId);
                goodsAnticipateVo.setCreatedDate(LocalDateTime.now());
                goodsAnticipateVo.setDelTag(0);

                //redis消息预约消息表
                LinkedList<Object[]> sqlAnt = CollectionUtil.linkedListObjectArr();
                sqlAnt.add(new Object[]{
//                        goodsAnticipateVo.getName(),
                        antId,
                        goodsAnticipateVo.getPeople(),
                        goodsAnticipateVo.getType(),
                        goodsAnticipateVo.getRule(),
                        goodsAnticipateVo.getCreatedDate(),
                        goodsAnticipateVo.getDelTag()
                });
                sendRedis("goblin_goods_anticipate", sqlAnt);

                //mongodb新增
                goblinMongoUtils.setGoblinGoodsAnticipateVo(goodsAnticipateVo);

                addAnticipateValues(antId, goodsAnticipateAddParam.getRule(), goodsAnticipateValueAddParam, goodsAnticipateAddParam.getPeople(), goodsAnticipateAddParam.getType());
            }
            return ResponseDto.success("1");
        }
        return ResponseDto.failure("参数有误");
    }

    public void addAnticipateValues(String antId, String rule, GoblinGoodsAnticipateValueAddParam goodsAnticipateValueAddParam, Integer people, Integer type) {
        //获取创建者uid
        String uid = CurrentUtil.getCurrentUid();
//        GoblinGoodsAnticipateValueVo goodsAnticipateValueVo = new GoblinGoodsAnticipateValueVo();
        GoblinGoodsAnticipateValueVo goodsAnticipateValueVo = GoblinGoodsAnticipateValueVo.getNew();
        goodsAnticipateValueVo.copy(goodsAnticipateValueAddParam);
        goodsAnticipateValueVo.setUid(uid);
        goodsAnticipateValueVo.setAntId(antId);
        goodsAnticipateValueVo.setRule(rule);
        goodsAnticipateValueVo.setCreatedDate(LocalDateTime.now());
        goodsAnticipateValueVo.setDelTag(0);
        goodsAnticipateValueVo.setAboutPeople(BigInteger.valueOf(0));
        goodsAnticipateValueVo.setActualPeople(BigInteger.valueOf(0));
        goodsAnticipateValueVo.setType(type);
        goodsAnticipateValueVo.setPeopleType(people);
        //redis消息
        //redis标识存入该sku处于预约列表
        goblinRedisUtils.setValue(goodsAnticipateValueVo);

        //保存mysql中间表
        LinkedList<Object[]> sqlValue = CollectionUtil.linkedListObjectArr();
        sqlValue.add(new Object[]{
                goodsAnticipateValueVo.getUid(),
                goodsAnticipateValueVo.getAntId(),
                goodsAnticipateValueVo.getSkuName(),
                goodsAnticipateValueVo.getSkuId(),
                goodsAnticipateValueVo.getSpuId(),
                goodsAnticipateValueVo.getAboutPeople(),
                goodsAnticipateValueVo.getActualPeople(),
                goodsAnticipateValueVo.getRule(),
                goodsAnticipateValueVo.getAboutStartDate(),
                goodsAnticipateValueVo.getAboutEndDate(),
                goodsAnticipateValueVo.getCreatedDate(),
                goodsAnticipateValueVo.getDelTag()
        });
        sendRedis("goblin_goods_anticipate_value", sqlValue);

        //存入mongodb中
        goblinMongoUtils.addAnticipateValues(goodsAnticipateValueVo);
    }

    @Override
    public ResponseDto<PageInfo<GoblinGoodsAnticipateValueVo>> list(GoblinGoodsAnticipateValueParam goodsAnticipateValueParam) {
        PageInfo<GoblinGoodsAnticipateValueVo> pageInfo = new PageInfo<>();
        String uid = CurrentUtil.getCurrentUid();
        HashMap<String, Object> map = goblinMongoUtils.getGoblinGoodsAnticipateValueVos(goodsAnticipateValueParam, uid);
        List<GoblinGoodsAnticipateValueVo> data = (List<GoblinGoodsAnticipateValueVo>) map.get("data");
        for (GoblinGoodsAnticipateValueVo anticipateValueVo : data) {
            //查询真实预约人数
            BigInteger autIdPeople = goblinRedisUtils.getSkuIdPeople(anticipateValueVo.getSkuId());
            autIdPeople = autIdPeople != null ? autIdPeople : BigInteger.valueOf(0);
            //预约人数   读取缓存的预约人数
            GoblinGoodsAnticipateValueVo aboutPeople = goblinRedisUtils.getValueBySkuId(anticipateValueVo.getSkuId());
            anticipateValueVo.setAboutPeople(aboutPeople != null ? aboutPeople.getAboutPeople() : BigInteger.valueOf(0));
            //实际预约人数
            anticipateValueVo.setActualPeople(autIdPeople);
            //设置预约状态
            anticipateValueVo.setState(GoblinAnticipateUtils.setState(anticipateValueVo.getAboutStartDate(), anticipateValueVo.getAboutEndDate()));
        }
        pageInfo.setPageNum(goodsAnticipateValueParam.getPageNum());
        pageInfo.setPageSize(20);
        pageInfo.setList(data);
        pageInfo.setTotal((Long) map.get("total"));
        return ResponseDto.success(pageInfo);
    }

    @Override
    public ResponseDto<Boolean> updatePeople(String skuId, BigInteger people) {
        //修改Mongodb
        goblinMongoUtils.updateGoblinGoodsAnticipateValueVoPeople(skuId, people);
        //修改redis
        GoblinGoodsAnticipateValueVo anticipateValueVo = goblinRedisUtils.getValueBySkuId(skuId);
        anticipateValueVo.setAboutPeople(people);
        goblinRedisUtils.setValue(anticipateValueVo);
        //修改mysql
        LinkedList<Object[]> sqlValue = CollectionUtil.linkedListObjectArr();
        sqlValue.add(new Object[]{
                people,
                skuId
        });
        sendRedis("goblin_goods_anticipate_value_update_proper", sqlValue);
        return ResponseDto.success();
    }

    @Override
    public ResponseDto<Boolean> delete(String skuId) {
        //更具skuId查询
        GoblinGoodsAnticipateValueVo goodsAnticipateValueVo = goblinRedisUtils.getValueBySkuId(skuId);
        String uid = CurrentUtil.getCurrentUid();
        if (!goodsAnticipateValueVo.getUid().equals(uid)) {
            return ResponseDto.failure("无权限删除");
        }
        goodsAnticipateValueVo.setState(GoblinAnticipateUtils.setState(goodsAnticipateValueVo.getAboutStartDate(), goodsAnticipateValueVo.getAboutEndDate()));
        //没有开启则可以删除预约
        if (!goodsAnticipateValueVo.getState().equals(0)) {
            return ResponseDto.failure("预约状态为已开启或已结束，不可删除！");
        }
        //删除sku助力相关
        goblinRedisUtils.delSharePeopleBySkuId(skuId);
        //mysql删除
        LinkedList<Object[]> sqlValue = CollectionUtil.linkedListObjectArr();
        sqlValue.add(new Object[]{
                skuId
        });
        //预约库删除
        sendRedis("goblin_goods_anticipate_value_delete", sqlValue);
        //删除mongodb
        goblinMongoUtils.delGoodsAnticipateValueVo(skuId);
        return ResponseDto.success();
    }

    @Override
    public AnticipateValueVo getAnticipateValueBySkuId(String skuId, int hasHead) {
        GoblinGoodsAnticipateValueVo anticipateValueVo = goblinRedisUtils.getValueBySkuId(skuId);
        AnticipateValueVo valueVo = AnticipateValueVo.getNew();
        if (anticipateValueVo != null) {
            valueVo = valueVo.copy(anticipateValueVo);
            valueVo.setState(GoblinAnticipateUtils.setState(valueVo.getAboutStartDate(), valueVo.getAboutEndDate()));
        } else {
            valueVo.setState(null);
            valueVo.setAboutEndDate(null);
            valueVo.setAboutStartDate(null);
            valueVo.setAboutPeople(BigInteger.ZERO);
            valueVo.setType(null);
            valueVo.setPeopleType(null);
            valueVo.setRule("");
        }
        if (hasHead == 1) {
            valueVo.setAboutAvatarList(goblinRedisUtils.getUserAvatar(skuId));
        } else {
            valueVo.setAboutAvatarList(CollectionUtil.linkedListString());
        }
        return valueVo;
    }

    public void sendRedis(String sqlKey, LinkedList<Object[]> sqlData) {
        LinkedList<String> sql = CollectionUtil.linkedListString();
        sql.add(SqlMapping.get(sqlKey));
        String sqlStr = SqlMapping.gets(sql, sqlData);
        queueUtils.sendMsgByRedis(
                MQConst.GoblinQueue.GOBLIN_STORE_MARKET.getKey(),
                sqlStr);
    }

}
