package com.zm.order.tool.server.service.impl;

import com.zm.order.tool.server.dao.OrderCommentDao;
import com.zm.order.tool.server.dao.OrderCommentDetailsDao;
import com.zm.order.tool.server.manager.CommonManager;
import com.zm.order.tool.server.manager.RedisManager;
import com.zm.order.tool.server.model.OrderComment;
import com.zm.order.tool.server.model.OrderCommentDetails;
import com.zm.order.tool.server.query.OrderCommentQuery;
import com.zm.order.tool.server.service.CommentService;
import com.zm.util.dto.Result;
import org.apache.lucene.util.NamedThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * @author zhuxiaofeng
 * @packageName: com.zm.order.tool.server.service.impl
 * @className: CommentServiceImpl
 * @date 2023/10/7 15:27
 */
@Service
public class CommentServiceImpl implements CommentService, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(CommentServiceImpl.class);

    @Autowired
    private CommonManager commonManager;

    @Autowired
    private RedisManager redisManager;

    @Autowired
    private OrderCommentDetailsDao detailsDao;

    @Autowired
    private OrderCommentDao commentDao;

    private BlockingQueue workQueue;

    private ExecutorService executorService;


    @Value("${sharding.db.size}")
    private int dbSize;

    @Value("${sharding.tb.size}")
    private int tbSize;

    private int size = 200;

    /**
     * 多线程配置
     */
    @Override
    public void afterPropertiesSet() {
        int coreSize = Runtime.getRuntime().availableProcessors();
        workQueue = new ArrayBlockingQueue(100);
        executorService = new ThreadPoolExecutor(3, 3, 1, TimeUnit.MINUTES,
                workQueue, new NamedThreadFactory("comment-update"),
                new ThreadPoolExecutor.AbortPolicy());
    }

    static int totalCount = 0;

    @Override
    public void orderCommentAddScore() {
        int count = 0;
        OrderCommentQuery query = new OrderCommentQuery();
        query.setSize(size);
        try {
            for (int i = 0; i < dbSize; i++) {
                for (int j = 0; j < tbSize; j++) {
                    Long lastId = null;
                    for (; ; ) {
                        query.setLastId(lastId);
                        while (workQueue.remainingCapacity() < 20) {
                            logger.info("workQueue size:{}", workQueue.size());
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }

                        List<OrderComment> list = commonManager.scanComment(query, i, j);
                        if (CollectionUtils.isEmpty(list)) {
                            break;
                        }
                        count += list.size();
                        lastId = list.get(list.size() - 1).getId();
                        logger.info("orderCommentAddScore last_id:{},count:{}, i:{},j:{}", lastId, count, i, j);
                        executorService.submit(() -> addScore(list));

                        Result<String> redisData = redisManager.get("history_orderCommentAddScore_shop");
                        if (redisData.isStatus() && Objects.nonNull(redisData.getData())) {
                            logger.info("[orderCommentAddScore] shut down！");
                            return;
                        }
                        if (list.size() < size) {
                            break;
                        }
                    }
                }
            }
            logger.info("orderCommentAddScore[end],count:{}", count);
        } catch (Exception e) {
            logger.error("orderCommentAddScore[error] cause by:{}", e);
            throw new RuntimeException("系统异常");
        }
    }

    private void addScore(List<OrderComment> list) {
        try {
            if (CollectionUtils.isEmpty(list)) {
                return;
            }
            List<String> orderNoList = new ArrayList<>(list.size());
            List<Long> sellerIdList = new ArrayList<>(list.size());
            for (OrderComment comment : list) {
                if (comment.getBizType().equals(5) || comment.getBizType().equals(6) || comment.getBizType().equals(7)) {
                    orderNoList.add(comment.getOrderNo());
                    sellerIdList.add(comment.getSellerId());
                }
            }
            if (CollectionUtils.isEmpty(sellerIdList)) {
                return;
            }
            if (CollectionUtils.isEmpty(orderNoList)) {
                return;
            }
            List<OrderCommentDetails> orderCommentDetails = detailsDao.selectByOrderNoList(orderNoList, sellerIdList);
            for (OrderCommentDetails details : orderCommentDetails) {
                if (details.getCommentType().equals(100)) {
                    if (Objects.nonNull(details.getCommentScore())) {
                        totalCount ++;
                        commentDao.updateByOrderNo(details.getCommentScore(), details.getOrderNo(), details.getSellerId());
                    }
                }
            }
            logger.info("orderCommentAddScore[running] listSize:{}, totalCount:{}", list.size(), totalCount);
        } catch (Throwable e) {
            logger.error("orderCommentAddScore[error] failed!, cause by:{}", e);
        }

    }
}
