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

import com.liquidnet.commons.lang.util.CollectionUtil;
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.GoblinArtistConst;
import com.liquidnet.service.goblin.constant.GoblinRedisConst;
import com.liquidnet.service.goblin.dto.vo.GoblinArtistAuthApplyVo;
import com.liquidnet.service.goblin.dto.vo.GoblinArtistTopicVo;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import com.liquidnet.service.goblin.util.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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 java.time.LocalDateTime;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 艺人授权过期后，自动将对应已上架专题改为下架
 */
@Slf4j
@Service
public class GoblinArtistTopicJobServiceImpl {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private GoblinRedisUtils goblinRedisUtils;
    @Autowired
    private QueueUtils queueUtils;

    public ResponseDto<String> offlineExpired() {
        LocalDateTime now = LocalDateTime.now();
        Set<String> validKeys = loadValidAuthKeys(now);

        List<GoblinArtistTopicVo> onlineTopics = mongoTemplate.find(
                new Query(Criteria.where("status").is(GoblinArtistConst.TOPIC_ONLINE)
                        .and("delFlg").is(GoblinArtistConst.DEL_NO)
                        .and("artistId").exists(true).ne("")),
                GoblinArtistTopicVo.class, GoblinArtistTopicVo.class.getSimpleName());
        if (onlineTopics == null || onlineTopics.isEmpty()) {
            return ResponseDto.success("无已上架专题");
        }

        List<GoblinArtistTopicVo> toOffline = onlineTopics.stream()
                .filter(t -> StringUtils.isNotBlank(t.getTopicId()))
                .filter(t -> StringUtils.isNotBlank(t.getArtistId()))
                .filter(t -> !validKeys.contains(t.getStoreId() + "_" + t.getArtistId()))
                .collect(Collectors.toList());
        if (toOffline.isEmpty()) {
            return ResponseDto.success("无需要下架的专题");
        }

        List<String> topicIds = toOffline.stream()
                .map(GoblinArtistTopicVo::getTopicId)
                .collect(Collectors.toList());
        mongoTemplate.updateMulti(
                new Query(Criteria.where("topicId").in(topicIds)),
                new Update().set("status", GoblinArtistConst.TOPIC_OFFLINE).set("updatedAt", now),
                GoblinArtistTopicVo.class.getSimpleName());

        LinkedList<String> sqls = CollectionUtil.linkedListString();
        LinkedList<Object[]> sqlObjs = CollectionUtil.linkedListObjectArr();
        for (String topicId : topicIds) {
            goblinRedisUtils.del(GoblinRedisConst.ARTIST_TOPIC + topicId);
            sqls.add(SqlMapping.get("goblin_artist_topic.status"));
            sqlObjs.add(new Object[]{GoblinArtistConst.TOPIC_OFFLINE, now, topicId});
        }
        queueUtils.sendMsgByRedis(MQConst.GoblinQueue.SQL_STORE.getKey(),
                SqlMapping.gets(sqls, sqlObjs));

        log.info("[艺人专题过期下架] 下架 {} 个专题, topicIds={}", topicIds.size(), topicIds);
        return ResponseDto.success("下架" + topicIds.size() + "个专题");
    }

    /** 仍有效授权：申请已通过且未过期 */
    private Set<String> loadValidAuthKeys(LocalDateTime now) {
        List<GoblinArtistAuthApplyVo> auths = mongoTemplate.find(
                new Query(Criteria.where("status").is(GoblinArtistConst.APPLY_APPROVED)
                        .and("authExpireAt").gt(now)),
                GoblinArtistAuthApplyVo.class, GoblinArtistAuthApplyVo.class.getSimpleName());
        if (auths == null || auths.isEmpty()) {
            return Collections.emptySet();
        }
        return auths.stream()
                .filter(a -> StringUtils.isNotBlank(a.getStoreId()) && StringUtils.isNotBlank(a.getArtistId()))
                .map(a -> a.getStoreId() + "_" + a.getArtistId())
                .collect(Collectors.toSet());
    }
}
