package com.sw.mes.fb.utils;

import com.sw.mes.core.utils.DateUtil;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
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.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExcelUtil {

    public static Map<String,List<Map<String, Object>>> getExcelInfo(MultipartFile mfile) throws Exception {

        if(mfile == null){
            throw new Exception("file is null!");
        }

        String filename = mfile.getOriginalFilename();
        if(filename == null){
            throw new Exception("file is not exist!");
        }

        try {
            if (!validateExcel(filename)) {// 验证文件名是否合格
                 throw new Exception("文件名不合格！");
            }
            boolean isExcel2003 = true;// 根据文件名判断文件是2003版本还是2007版本
            if (isExcel2007(filename)) {
                isExcel2003 = false;
            }
            return createExcel(mfile.getInputStream(), isExcel2003);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("文件读取异常！");//zcc 修改 抛出异常

        }


    }

    public static Map<String,List<Map<String, Object>>> createExcel(InputStream inputStream, boolean isExcel2003){
        try {
            Workbook wb = null;
            if (isExcel2003) {// 当excel是2003时,创建excel2003
                wb = new HSSFWorkbook(inputStream);
            } else {// 当excel是2007时,创建excel2007
                wb = new XSSFWorkbook(inputStream);
            }
            return readExcelValue(wb);// 读取Excel里面客户的信息
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new HashMap<>();
    }

    /**
     * 读取Excel里面设备的信息
     *
     * @param wb
     * @return
     */
    private static Map<String,List<Map<String, Object>>> readExcelValue(Workbook wb) {

        Map<String,List<Map<String, Object>>> listMapTotal = new HashMap();

        for (int s = 0; s < wb.getNumberOfSheets(); s++) {
            Sheet sheet = wb.getSheetAt(s);
            String sheetName = sheet.getSheetName();

            // 得到Excel的行数
            int totalRows = sheet.getPhysicalNumberOfRows();

            if (totalRows < 1) continue;

            Row row1 = sheet.getRow(0);
            int rowCount = row1.getLastCellNum();
            Map<Integer, String> rowMap = new HashMap<>();
            String tempValue = "";
            for(int n = 0; n < rowCount; n++) {
                tempValue = getCellValue(row1.getCell(n));
                rowMap.put(n, tempValue);
            }

            List<Map<String,Object>> mapList = new ArrayList<>();
            for (int i = 1; i < totalRows; i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;
                Map map = new HashMap();

                for(int r = 0; r < row.getLastCellNum(); r++) {
                    if(getCellValue(row.getCell(r)) != null){
                        map.put(rowMap.get(r), getCellValue(row.getCell(r)));
                    }
                }
                if(!map.isEmpty()){
                    mapList.add(map);
                }
            }

            if(mapList.size() > 0 ){
                listMapTotal.put(sheetName,mapList);
            }
        }

        return listMapTotal;
    }

    /**
     * 获取单元格的值
     * @param cell
     * @return
     */
    public static String getCellValue(Cell cell){
        if(cell == null) return "";
        if(cell.getCellType() == Cell.CELL_TYPE_STRING){
            return cell.getStringCellValue();
        }else if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){
            return String.valueOf(cell.getBooleanCellValue());
        }else if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){
            try {
                return String.valueOf(cell.getNumericCellValue());
            } catch (IllegalStateException e) {
                return String.valueOf(cell.getRichStringCellValue());
            }
        }else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
            if (HSSFDateUtil.isCellDateFormatted(cell)) {
                return DateUtil.formatDate(cell.getDateCellValue(), DateUtil.longFormat);
            }
            cell.setCellType(Cell.CELL_TYPE_STRING);//zcc-修改 讲数字类型以文本形式进行读取
            return String.valueOf(cell.getStringCellValue());
        }
        return "";
    }

    /**
     * 判断指定的单元格是否是合并单元格
     * @param sheet
     * @param row 行下标
     * @param column 列下标
     * @return
     */
    private static boolean isMergedRegion(Sheet sheet, int row , int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if(row >= firstRow && row <= lastRow){
                if(column >= firstColumn && column <= lastColumn){
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取合并单元格的值
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    public static String getMergedRegionValue(Sheet sheet , int row , int column){
        int sheetMergeCount = sheet.getNumMergedRegions();

        for(int i = 0 ; i < sheetMergeCount ; i++){
            CellRangeAddress ca = sheet.getMergedRegion(i);
            int firstColumn = ca.getFirstColumn();
            int lastColumn = ca.getLastColumn();
            int firstRow = ca.getFirstRow();
            int lastRow = ca.getLastRow();

            if(row >= firstRow && row <= lastRow){
                if(column >= firstColumn && column <= lastColumn){
                    Row fRow = sheet.getRow(firstRow);
                    Cell fCell = fRow.getCell(firstColumn);
                    return getCellValue(fCell) ;
                }
            }
        }
        return null ;
    }

    /**
     * 验证EXCEL文件
     *
     * @param filePath
     * @return
     */
    public static boolean validateExcel(String filePath) {
        if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
            return false;
        }
        return true;
    }

    // @描述：是否是2003的excel，返回true是2003
    public static boolean isExcel2003(String filePath) {
        return filePath.matches("^.+\\.(?i)(xls)$");
    }

    // @描述：是否是2007的excel，返回true是2007
    public static boolean isExcel2007(String filePath) {
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }

}
