package com.liquidnet.service.adam.service.impl.admin;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.vo.AdamMemberPriceVo;
import com.liquidnet.service.adam.entity.AdamMemberPrice;
import com.liquidnet.service.adam.mapper.AdamMemberPriceMapper;
import com.liquidnet.service.adam.service.admin.IAdamMemberPriceService;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
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.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class AdamMemberPriceServiceImpl extends ServiceImpl<AdamMemberPriceMapper, AdamMemberPrice> implements IAdamMemberPriceService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    MongoConverter mongoConverter;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    AdamMemberPriceMapper adamMemberPriceMapper;

    @Override
    public List<AdamMemberPrice> list(String memberId) {
        Map<String,Object> map = new HashMap<>();
        map.put("member_id", memberId);
        List<AdamMemberPrice> adamMemberPrices = adamMemberPriceMapper.selectByMap(map);
        return adamMemberPrices;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void add(AdamMemberPrice info) {
        // mysql
        info.setMemberPriceId(IDGenerator.nextSnowId().toString());
        info.setCreatedAt(LocalDateTime.now());
        adamMemberPriceMapper.insert(info);
        // mongo
        AdamMemberPriceVo vo = new AdamMemberPriceVo();
        BeanUtils.copyProperties(info, vo);
        vo.setCreatedAt(DateUtil.format(info.getCreatedAt(), DateUtil.Formatter.yyyyMMddHHmmss));

        mongoTemplate.insert(vo, AdamMemberPriceVo.class.getSimpleName());
        // redis
        redisUtil.hset(AdamRedisConst.INFO_MEMBERS_PRICE_INFO.concat(info.getMemberId()), vo.getMemberPriceId(), vo);
    }

    @Override
    public AdamMemberPriceVo query(String memberId, String memberPriceId) {
        AdamMemberPriceVo priceVo = (AdamMemberPriceVo) redisUtil.hget(AdamRedisConst.INFO_MEMBERS_PRICE_INFO.concat(memberId), memberPriceId);
        if (null == priceVo) {
            priceVo = mongoTemplate.findOne(Query.query(Criteria.where("memberPriceId").is(memberPriceId)), AdamMemberPriceVo.class, AdamMemberPriceVo.class.getSimpleName());

            if (null != priceVo) redisUtil.hset(AdamRedisConst.INFO_MEMBERS_PRICE_INFO.concat(memberId), memberPriceId, priceVo);
        }
        return priceVo;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean edit(AdamMemberPrice info) {
        try {
            String memberPriceId = info.getMemberPriceId();
            LocalDateTime updatedAt = LocalDateTime.now();
            info.setUpdatedAt(updatedAt);
            // mysql
            adamMemberPriceMapper.update(
                    info, new UpdateWrapper<AdamMemberPrice>().eq("member_price_id", memberPriceId));
            // mongo
            BasicDBObject object = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(info)));
            Document doc = mongoTemplate.getCollection(AdamMemberPrice.class.getSimpleName())
                    .findOneAndUpdate(
                            Query.query(Criteria.where("memberPriceId").is(memberPriceId)).getQueryObject(),
                            object,
                            new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
                    );
            // reids
            redisUtil.hset(AdamRedisConst.INFO_MEMBERS_PRICE_INFO.concat(info.getMemberId()), info.getMemberPriceId(), info);
        } catch (Exception e){
            return false;
        }
        return true;
    }
}
