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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.dto.GoblinStoreMarketDto;
import com.liquidnet.service.goblin.dto.vo.GoblinStoreCouponBasicVo;
import com.liquidnet.service.goblin.entity.GoblinStoreCoupon;
import com.liquidnet.service.goblin.mapper.GoblinStoreCouponMapper;
import com.liquidnet.service.platform.utils.GoblinRedisUtils;
import com.mongodb.client.result.UpdateResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PlatformGoblinStoreCouponService extends ServiceImpl<GoblinStoreCouponMapper, GoblinStoreCoupon> {
    @Autowired
    private GoblinStoreCouponMapper goblinStoreCouponMapper;
    @Autowired
    private GoblinRedisUtils goblinRedisUtils;
    @Autowired
    private MongoTemplate mongoTemplate;

    public int activityStartProcessing(LocalDateTime now) {
        LambdaQueryWrapper<GoblinStoreCoupon> queryWrapper = Wrappers.lambdaQuery(GoblinStoreCoupon.class);
        queryWrapper.eq(GoblinStoreCoupon::getDelFlg, "0");
        queryWrapper.eq(GoblinStoreCoupon::getState, "0");
        queryWrapper.le(GoblinStoreCoupon::getStartTime, now);

        List<GoblinStoreCoupon> storeCouponList = null;
        try {
            storeCouponList = this.list(queryWrapper);
            if (!CollectionUtils.isEmpty(storeCouponList)) {
                List<String> storeCouponIdList = storeCouponList.stream().map(GoblinStoreCoupon::getStoreCouponId).collect(Collectors.toList());

                LambdaUpdateWrapper<GoblinStoreCoupon> updateWrapper = Wrappers.lambdaUpdate(GoblinStoreCoupon.class);
                updateWrapper.eq(GoblinStoreCoupon::getDelFlg, "0");
                updateWrapper.eq(GoblinStoreCoupon::getState, "0");
                updateWrapper.in(GoblinStoreCoupon::getStoreCouponId, storeCouponIdList);

                updateWrapper.set(GoblinStoreCoupon::getState, "1");
                updateWrapper.set(GoblinStoreCoupon::getUpdatedAt, now);
                updateWrapper.set(GoblinStoreCoupon::getUpdatedBy, "task");

                if (this.update(updateWrapper)) {
                    UpdateResult updateResult = mongoTemplate.getCollection(GoblinStoreCouponBasicVo.class.getSimpleName()).updateMany(
                            Query.query(Criteria.where("delFlg").is("0").and("state").is("0").and("storeCouponId").in(storeCouponIdList)).getQueryObject(),
                            Update.update("state", "1").set("updatedAt", now.minusHours(8)).set("updatedBy", "task").getUpdateObject()
                    );
                    if (updateResult.getModifiedCount() <= 0) {
                        log.warn("###商铺活动:优惠券处理失败:[now={},storeCouponIdList={}]", now, JsonUtils.toJson(storeCouponIdList));
                    } else {
                        storeCouponList.forEach(storeCoupon -> {
                            GoblinStoreMarketDto storeMarketDto = GoblinStoreMarketDto.getNew();
                            storeMarketDto.setId(storeCoupon.getStoreCouponId());
                            storeMarketDto.setType(1);

                            goblinRedisUtils.addStoreMarketDto(storeCoupon.getStoreId(), storeMarketDto);

                            goblinRedisUtils.del(GoblinRedisConst.STORE_COUPON.concat(storeCoupon.getStoreCouponId()));
                        });
                        return storeCouponList.size();
                    }
                }
            }
        } catch (Exception e) {
            log.error("###商铺活动:优惠券处理异常[now={},storeCouponList.size={}]", now, null == storeCouponList ? -1 : storeCouponList.size(), e);
        }
        return 0;
    }

    public int activityStopProcessing(LocalDateTime now) {
        LambdaQueryWrapper<GoblinStoreCoupon> queryWrapper = Wrappers.lambdaQuery(GoblinStoreCoupon.class);
        queryWrapper.eq(GoblinStoreCoupon::getDelFlg, "0");
        queryWrapper.eq(GoblinStoreCoupon::getState, "1");
        queryWrapper.le(GoblinStoreCoupon::getEndTime, now);

        List<GoblinStoreCoupon> storeCouponList = null;
        try {
            storeCouponList = this.list(queryWrapper);
            if (!CollectionUtils.isEmpty(storeCouponList)) {
                List<String> storeCouponIdList = storeCouponList.stream().map(GoblinStoreCoupon::getStoreCouponId).collect(Collectors.toList());

                LambdaUpdateWrapper<GoblinStoreCoupon> updateWrapper = Wrappers.lambdaUpdate(GoblinStoreCoupon.class);
                updateWrapper.eq(GoblinStoreCoupon::getDelFlg, "0");
                updateWrapper.eq(GoblinStoreCoupon::getState, "1");
                updateWrapper.in(GoblinStoreCoupon::getStoreCouponId, storeCouponIdList);

                updateWrapper.set(GoblinStoreCoupon::getState, "2");
                updateWrapper.set(GoblinStoreCoupon::getUpdatedAt, now);
                updateWrapper.set(GoblinStoreCoupon::getUpdatedBy, "task");
                if (this.update(updateWrapper)) {
                    UpdateResult updateResult = mongoTemplate.getCollection(GoblinStoreCouponBasicVo.class.getSimpleName()).updateMany(
                            Query.query(Criteria.where("delFlg").is("0").and("state").is("1").and("storeCouponId").in(storeCouponIdList)).getQueryObject(),
                            Update.update("state", "2").set("updatedAt", now.minusHours(8)).set("updatedBy", "task").getUpdateObject()
                    );
                    if (updateResult.getModifiedCount() <= 0) {
                        log.warn("###商铺活动:优惠券处理失败:[now={},storeCouponIdList={}]", now, JsonUtils.toJson(storeCouponIdList));
                    } else {
                        storeCouponList.forEach(storeCoupon -> {
                            GoblinStoreMarketDto storeMarketDto = GoblinStoreMarketDto.getNew();
                            storeMarketDto.setId(storeCoupon.getStoreCouponId());
                            storeMarketDto.setType(1);

                            goblinRedisUtils.delStoreMarketDto(storeCoupon.getStoreId(), storeMarketDto);

                            goblinRedisUtils.del(GoblinRedisConst.STORE_COUPON.concat(storeCoupon.getStoreCouponId()));
                        });
                        return storeCouponList.size();
                    }
                }
            }
        } catch (Exception e) {
            log.error("###商铺活动:优惠券处理异常[now={},storeCouponList.size={}]", now, null == storeCouponList ? -1 : storeCouponList.size(), e);
        }
        return 0;
    }
}
