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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.BeanUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dao.BannerDetailsDao;
import com.liquidnet.service.kylin.dao.BannerDetailsListDao;
import com.liquidnet.service.kylin.dto.param.BannersParam;
import com.liquidnet.service.kylin.dto.param.BannersSearchParam;
import com.liquidnet.service.kylin.dto.vo.BannersVo;
import com.liquidnet.service.kylin.entity.KylinBanners;
import com.liquidnet.service.kylin.mapper.KylinBannersMapper;
import com.liquidnet.service.kylin.service.admin.IKylinBannersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import com.mysql.cj.util.StringUtils;
import org.bson.Document;
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 java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 轮播图 服务实现类
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-05-02
 */
@Service
public class KylinBannersServiceImpl extends ServiceImpl<KylinBannersMapper, KylinBanners> implements IKylinBannersService {

    @Autowired
    private KylinBannersMapper bannersMapper;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private MongoConverter mongoConverter;

    @Autowired
    RedisUtil redisUtil;

    public boolean create(BannersParam bannersParam) {
        try {
            String bannersId = IDGenerator.nextSnowId().toString();
            LocalDateTime createdAt = LocalDateTime.now();
            bannersMapper.insert(bannersParam.getFields(bannersId, createdAt));

            BannersVo bannersVo = new BannersVo();
            BeanUtils.copyProperties(bannersParam, bannersVo);
            bannersVo.setBannersId(bannersId);
            bannersVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            bannersVo.setUpdatedAt("");
            bannersVo.setIsDeleted(1);
            if (null == bannersParam.getSort()) {
                bannersVo.setSort(0);
            }
            if (StringUtils.isNullOrEmpty(bannersParam.getComment())) {
                bannersVo.setComment("");
            }
            mongoTemplate.insert(bannersVo, BannersVo.class.getSimpleName());

            redisUtil.hset(KylinRedisConst.BANNERS, bannersId, bannersVo);

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public boolean update(BannersParam bannersParam) {
        try {
            String bannersId = bannersParam.getBannersId();
            LocalDateTime updatedAt = LocalDateTime.now();

            KylinBanners params = bannersParam.getFields(null, null);
            params.setUpdatedAt(updatedAt);
            bannersMapper.update(params, new UpdateWrapper<KylinBanners>().eq("banners_id", bannersId));

            BannersVo bannersVo = new BannersVo();
            BeanUtils.copyProperties(bannersParam, bannersVo);
            bannersVo.setBannersId(bannersId);
            bannersVo.setUpdatedAt(updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            BasicDBObject object = new BasicDBObject("$set", JSON.parse(JsonUtils.toJson(bannersVo)));
            Document doc = mongoTemplate.getCollection(BannersVo.class.getSimpleName()).findOneAndUpdate(
                    Query.query(Criteria.where("bannersId").is(bannersId)).getQueryObject(),
                    object,
                    new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
            );

            redisUtil.hset(KylinRedisConst.BANNERS, bannersId, JsonUtils.fromJson(doc.toJson(), BannersVo.class));

            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public BannerDetailsDao detail(String bannersId) {
        BannerDetailsDao data = bannersMapper.detail(bannersId);
        return data;
    }

    public List<BannerDetailsListDao> bannerList(BannersSearchParam bannersSearchParam) {
        try {
            bannersSearchParam.setPage((bannersSearchParam.getPage() - 1) * bannersSearchParam.getSize());

            List<BannerDetailsListDao> data = bannersMapper.searchBannersList(BeanUtil.convertBeanToMap(bannersSearchParam));
            return data;
        } catch (Exception e) {
            return new ArrayList<>();
        }
    }
    public Long bannerListCount(BannersSearchParam bannersSearchParam) {
        try {
            Long count = bannersMapper.searchBannersCount(BeanUtil.convertBeanToMap(bannersSearchParam));
            return count;
        } catch (Exception e) {
            return 0L;
        }
    }

    public Boolean delete(String bannersId) {
        try {
            LocalDateTime updatedAt = LocalDateTime.now();

            KylinBanners kylinBanners = new KylinBanners();
            kylinBanners.setUpdatedAt(updatedAt);
            kylinBanners.setIsDeleted(0);
            bannersMapper.update(kylinBanners
                    , new UpdateWrapper<KylinBanners>().eq("banners_id", bannersId));

            // mongo 操作
            HashMap<String, Object> map = new HashMap<>();
            map.put("updatedAt", updatedAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            map.put("isDeleted", 0);

            BasicDBObject object = new BasicDBObject("$set", mongoConverter.convertToMongoType(map));
            Document doc = mongoTemplate.getCollection(BannersVo.class.getSimpleName()).findOneAndUpdate(
                    Query.query(Criteria.where("bannersId").is(bannersId)).getQueryObject(),
                    object,
                    new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
            );

            // redis 操作
            redisUtil.hset(KylinRedisConst.BANNERS, bannersId, JsonUtils.fromJson(doc.toJson(), BannersVo.class));

            return true;
        } catch (Exception e) {
            return false;
        }
    }

}
