package com.jsc.dsp.utils;

import com.jsc.dsp.dao.EsDataNewsRepository;
import com.jsc.dsp.dao.IndeximosRepository;
import com.jsc.dsp.model.EsDataNewsView;
import com.jsc.dsp.model.Indeximos;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
public class DatabaseConnector {

    @Resource
    IndeximosRepository indeximosRepository;

    @Resource
    EsDataNewsRepository esDataNewsRepository;

    @Value("${custom.excelOutputPath}")
    String excelOutputPath;

    private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    public void insertIntoDB(List<Indeximos> objectList) {
        try {
            indeximosRepository.saveAll(objectList);
        } catch (Exception e) {
            logger.warn("Fail to insert data to Database");
            logger.warn(e.getMessage());
        }
    }


    public boolean hasField(Class<?> clazz, String fieldName) {
        try {
            clazz.getDeclaredField(fieldName);
            return true;
        } catch (NoSuchFieldException e) {
            return false;
        }
    }

    public String getFieldType(Class<?> clazz, String fieldName) {
        try {
            Field field = clazz.getDeclaredField(fieldName);
            return field.getType().getName();
        } catch (NoSuchFieldException e) {
            return "";
        }
    }

    public void exportToXlsx(String startTime) {
        try {
            Path dirPath = Paths.get(excelOutputPath);
            if (!Files.exists(dirPath)) {
                Files.createDirectories(dirPath);
            }
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String fileName = "data_news-" + timestamp + "-001.xlsx";
            Path filePath = dirPath.resolve(fileName);

            List<EsDataNewsView> esDataNewsViewList = esDataNewsRepository.findAllByEsLoadtimeAfter(startTime);
            if (!esDataNewsViewList.isEmpty()) {
                Field[] fields = esDataNewsViewList.get(0).getClass().getDeclaredFields();
                try (Workbook workbook = new XSSFWorkbook();
                     ByteArrayOutputStream out = new ByteArrayOutputStream()) {

                    Sheet sheet = workbook.createSheet("data");

                    // 创建表头
                    Row headerRow = sheet.createRow(0);
                    CellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    for (int i = 0; i < fields.length; i++) {
                        Cell cell = headerRow.createCell(i);
                        String formField = formField(fields[i]);
                        cell.setCellValue(formField);
                        cell.setCellStyle(headerStyle);
                    }
                    // 填充数据
                    int rowNum = 1;
                    for (EsDataNewsView item : esDataNewsViewList) {
                        if (item.getFile() == null || item.getFile().length() < 5) {
                            continue;
                        } else {
                            String fileFullPath = item.getFile();
                            int i = fileFullPath.indexOf(File.separator);
                            item.setFile(fileFullPath.substring(i + 1));
                        }
                        Row row = sheet.createRow(rowNum++);
                        logger.debug("导出excel第" + rowNum + "行");
                        row.createCell(0).setCellValue(item.getEsSid());
                        row.createCell(1).setCellValue(item.getEsAuthors());
                        row.createCell(2).setCellValue(item.getEsCarriertype());
                        row.createCell(3).setCellValue(item.getEsCatalog());
                        row.createCell(4).setCellValue(item.getEsCollection());
                        row.createCell(5).setCellValue(item.getEsDoclength());
                        row.createCell(6).setCellValue(item.getEsLang());
                        row.createCell(7).setCellValue(item.getEsLasttime());
                        if (item.getEsLinks().length() > 10000) {
                            row.createCell(8).setCellValue(item.getEsLinks().substring(0, 10000));
                        } else {
                            row.createCell(8).setCellValue(item.getEsLinks());
                        }
                        row.createCell(9).setCellValue(item.getEsLoadtime());
                        row.createCell(10).setCellValue(item.getEsSitename());
                        row.createCell(11).setCellValue(item.getEsSrcname());
                        row.createCell(12).setCellValue(item.getEsUrlcontent());
                        row.createCell(13).setCellValue(item.getEsUrlcontentRaw());
                        row.createCell(14).setCellValue(item.getEsUrlimage());
                        row.createCell(15).setCellValue(item.getEsUrlname());
                        row.createCell(16).setCellValue(item.getEsUrltime());
                        row.createCell(17).setCellValue(item.getEsUrltitle());
                        row.createCell(18).setCellValue(item.getEsUrltitleRaw());
                        row.createCell(19).setCellValue(item.getEsAbstract());
                        row.createCell(20).setCellValue(item.getEsKeywords());
                        row.createCell(21).setCellValue(item.getFile());
                    }
                    logger.info("完成excel数据写入，共" + rowNum + "行");

                    // 自动调整列宽
                    for (int i = 0; i < fields.length; i++) {
                        sheet.autoSizeColumn(i);
                    }

                    workbook.write(out);

                    try (FileOutputStream fos = new FileOutputStream(filePath.toFile())) {
                        workbook.write(fos);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            logger.info("excel导出完成！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String formField(Field field) {
        String fieldString = field.getName();
        return StringUtils.camelToSnake(fieldString);
    }

}
