package com.kiisoo.ic.job.count;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kiisoo.ic.common.utils.ExcelUtils;
import com.kiisoo.ic.config.WxCpConfiguration;
import com.kiisoo.ic.employee.entity.PrivilageCpUserDO;
import com.kiisoo.ic.employee.mapper.PrivilageCpUserDOMapper;
import com.kiisoo.ic.store.entity.PoiStore;
import com.kiisoo.ic.store.entity.PrivilageCpUserStoreDO;
import com.kiisoo.ic.store.mapper.PrivilageCpUserStoreDOMapper;
import com.kiisoo.ic.system.entity.SysTaskDO;
import com.kiisoo.ic.system.mapper.SysTaskDOMapper;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static com.kiisoo.ic.config.WxCpConfiguration.APPLICATIONID;
import static com.kiisoo.ic.store.constant.Constants.DATABASE_CODE_KEY;
import static com.kiisoo.ic.system.constant.SysTaskConstant.TASK_STATUS_FINISHED;

/**
 * Disruptor多个消费者不重复处理生产者发送过来的消息
 */
@Service
@Slf4j
public class CustomerCountJob {


    // 指定 ring buffer字节大小，必需为2的N次方(能将求模运算转为位运算提高效率 )，否则影响性能
    private static final int BUFFER_SIZE = 1024 * 1024;
    //固定线程数
    private static final int THREAD_NUMBERS = 50;


    @Autowired
    private PrivilageCpUserDOMapper privilageCpUserDOMapper;
    @Autowired
    private PrivilageCpUserStoreDOMapper privilageCpUserStoreDOMapper;
    @Autowired
    private SysTaskDOMapper sysTaskDOMapper;


    public void handle(Boolean isAll,SysTaskDO sysTaskDO) throws WxErrorException, IOException {

        //创建线程池
        ExecutorService executors = Executors.newFixedThreadPool(THREAD_NUMBERS);
        // 创建缓冲池
        Disruptor<CountDTOMessage> disruptor = new Disruptor<>(new CountDTOMessageFactory(), BUFFER_SIZE, executors,
                ProducerType.SINGLE, new BlockingWaitStrategy());
        RingBuffer<CountDTOMessage> ringBuffer = disruptor.getRingBuffer();

        // 创建100个消费者来处理同一个生产者发的消息(这100个消费者不重复消费消息)
        CountDTOMessageGroupConsumer[] consumers = new CountDTOMessageGroupConsumer[THREAD_NUMBERS];
        for (int i = 0; i < consumers.length; i++) {
            consumers[i] = new CountDTOMessageGroupConsumer();
        }

        disruptor.handleEventsWithWorkerPool(consumers);

        disruptor.start();

        CountDTOMessageEventProducer producer = new CountDTOMessageEventProducer(ringBuffer, privilageCpUserDOMapper);

        List<String> cpUserIds = new ArrayList<>();
        if (isAll){
            File file = new File("/root/account.xls");
            if (file != null) {
                //获取文件名
                String fileName = file.getAbsolutePath();
                InputStream fileInput = new FileInputStream(file);
                // 根据后缀创建EXCEL对象
                Workbook book;
                if (ExcelUtils.isExcel2007(fileName)) {
                    book = new XSSFWorkbook(fileInput);
                } else {
                    book = new HSSFWorkbook(fileInput);
                }

                // 得到第一个sheet
                Sheet sheet = book.getSheetAt(0);
                // 得到Excel的行数
                int totalRows = sheet.getPhysicalNumberOfRows();

                // 循环Excel行数,获取数据
                for (int r = 1; r < totalRows; r++) {
                    Row dataRow = sheet.getRow(r);
                    if (dataRow == null) {
                        continue;
                    }
                    dataRow.getCell(0).setCellType(CellType.STRING);
                    String cpUserId = dataRow.getCell(0).getStringCellValue();
                    cpUserIds.add(cpUserId);
                }
            }
        }else {
            List<PrivilageCpUserStoreDO> privilageCpUserStoreDOS = privilageCpUserStoreDOMapper.selectList(null);
            List<Long> ids = privilageCpUserStoreDOS.stream().map(privilageCpUserStoreDO -> privilageCpUserStoreDO.getCpUserId()).collect(Collectors.toList());
            QueryWrapper<PrivilageCpUserDO> qw = new QueryWrapper<>();
            qw.in("id",ids);
            List<PrivilageCpUserDO> privilageCpUserDOS = privilageCpUserDOMapper.selectList(qw);
            cpUserIds = privilageCpUserDOS.stream().map(privilageCpUserDO -> privilageCpUserDO.getCpUserId()).collect(Collectors.toList());
        }


        int index =0;
        for (String cpUserId : cpUserIds) {
            producer.produceData(index,cpUserId);
            index++;
        }

        disruptor.shutdown();

        if (sysTaskDO!=null){
            sysTaskDO.setStatus(TASK_STATUS_FINISHED);
            sysTaskDO.setUpdateTime(new Date());
            sysTaskDOMapper.updateById(sysTaskDO);
            System.out.println(sysTaskDO);
        }
    }
}
