package com.bonus.hn.bearing.capacity.backstage.manager.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author bonus
 */
public class ImportNoPhotoExcelHelper {

    public static List<?> readExcel(MultipartFile file, Class<?> mClass) throws Exception {
        String fileName = file.getOriginalFilename();
        System.out.println("OriginalFilename：" + fileName);
        if (!StringUtils.endsWithAny(fileName, ".xls", ".xlsx")) {
            throw new RuntimeException("不支持excel以外的文件导入！");
        }
        List<?> list = new ArrayList<>();
        InputStream inputStream = file.getInputStream();
        String className = mClass.getSimpleName();
        System.out.println("className：" + className);
        //根据指定的文件输入流导入Excel从而产生Workbook对象
        Workbook workbook = null;
        Sheet sheet = null;
        Map<String, PictureData> mapData = null;
        if (fileName.endsWith(".xls")) {
            // throw new RuntimeException("格式错误请使用.xlsx格式文件");
            workbook = new HSSFWorkbook(inputStream);
            //获取Excel文档中的第一个表单
            sheet = workbook.getSheetAt(0);
            if (!checkModal(sheet, className)) {
                throw new RuntimeException("模板错误，请重新选择模板！");
            }
        } else if (fileName.endsWith(".xlsx")) {
            workbook = new XSSFWorkbook(inputStream);
            //获取Excel文档中的第一个表单
            sheet = workbook.getSheetAt(0);
            if (!checkModal(sheet, className)) {
                throw new RuntimeException("模板错误，请重新选择模板！");
            }
//            mapData = getPicturesXlsx((XSSFSheet) sheet, className);
        }
        List<String> filenames = new ArrayList<>();

        switch (className) {
            case "SysOrg":
            case "SysOrgWorker":
            case "BmProject":
            case "BmProjectWorkerBl":
            case "BmProjectWorker":
                System.out.println("开始读取并写入图片");
                filenames = writeImg(mapData, className);
                System.err.println("图片：" + filenames);
                break;
            case "CheckPunishItemBean":
                System.err.println("无需读取图片");
                break;
            case "WorkerRecordBean":
                System.err.println("无需读取图片");
                break;
            case "OwnerDefectListBean":
                System.err.println("无需读取图片");
                break;
            case "DrawingAndQuantityManagerBean":
                System.err.println("无需读取图片");
                break;
            case "NegativeResultBean":
                System.err.println("无需读取图片");
                break;
            default:
                break;
        }
        int sheetCount = workbook.getNumberOfSheets();
        System.out.println("Sheet(表单)数量：" + sheetCount);
        System.err.println("filenames:" + filenames);
        //获得最后一条记录得的行号，从0开始
        int totalRowNum = sheet.getLastRowNum();
        System.out.println("总记录数：" + (totalRowNum + 1));
        list = createBean(sheet, mClass, filenames);
        inputStream.close();
        return list;
    }

    private static boolean checkModal(Sheet sheet, String className) {
        int colNum = 0;
        if (className.equals("UploadPayrollBean")){
            colNum = sheet.getRow(1).getLastCellNum();
        }else if (className.equals("CareerBean")){
            colNum = sheet.getRow(1).getLastCellNum();
        }else if (className.equals("SubsidiaryCompanyBean")){
            colNum = sheet.getRow(1).getLastCellNum();
        }else if (className.equals("SelfOwnedBean")){
            colNum = sheet.getRow(1).getLastCellNum();
        }else if (className.equals("ProjectBean")){
            colNum = sheet.getRow(1).getLastCellNum();
        }else{
            colNum = sheet.getRow(0).getLastCellNum();
        }
        switch (className) {
            //分公司人员库导入Bean
            case "SubsidiaryCompanyBean":
                return colNum == 7;
            //分包单位人员库导入Bean
            case "SubcontractorBean":
                return colNum == 7;
            //自有单位人员库导入Bean
            case "SelfOwnedBean":
                return colNum == 7;
            //工机具导入Bean
            case "ProjectBean":
                return colNum == 7;
            //杆塔导入Bean
            case "TowerProjectBean":
                return colNum == 4;
            default:
                break;
        }
        return false;
    }

    private static List<JSONObject> createBean(Sheet sheet, Class<?> mClass, List<String> filename) throws Exception {
        if (sheet == null || sheet.getLastRowNum() < 0) {
            return null;
        }
        List<JSONObject> list = new ArrayList<>();
        // 总列数
        int last = sheet.getRow(0).getLastCellNum();
        System.out.println("列数：" + last);
        try {
            //对Sheet中的每一行进行迭代
            int k = 0;
            for (Row row : sheet) {
                k++;
                if (row == null) continue;
                JSONObject obj = new JSONObject();
                // 第一行是标题栏
                switch (mClass.getSimpleName()) {
                    case "SubsidiaryCompanyBean":
                        if (row.getRowNum() < 3) continue;
                        break;
                    case "SubcontractorBean":
                        if (row.getRowNum() < 3) continue;
                        break;
                    case "SelfOwnedBean":
                        if (row.getRowNum() < 3) continue;
                        break;
                    case "ProjectBean":
                        if (row.getRowNum() < 2) continue;
                        break;
                    case "TowerProjectBean":
                        if (row.getRowNum() < 4) continue;
                        break;
                    default:
                        if (row.getRowNum() < 1) continue;
                        break;
                }
                boolean isBlankRow = true;
                for (Cell c : row) {
                    if (c.getCellType() != Cell.CELL_TYPE_BLANK) {
                        isBlankRow = false;
                        break;
                    }
                }
                if (isBlankRow) {
                    System.err.println("k:" + k);
                    throw new RuntimeException("模板中含有无效的空行，请删除多余的空行后再导入！");
                }
                obj.put("rowNo", row.getRowNum() + 1);
                switch (mClass.getSimpleName()) {
                    case "SubsidiaryCompanyBean":
                        setExcleTString(7, row, 0);
                        if (row.getCell(1) != null)
                            obj.put("personName", row.getCell(1).getStringCellValue());
                        if (row.getCell(2) != null)
                            obj.put("sex", row.getCell(2).getStringCellValue());
                        if (row.getCell(3) != null)
                            obj.put("nation", row.getCell(3).getStringCellValue());
                        if (row.getCell(4) != null)
                            obj.put("id", row.getCell(4).getStringCellValue());
                        if (row.getCell(5) != null)
                            obj.put("certificate", row.getCell(5).getStringCellValue());
                        if (row.getCell(6) != null)
                            obj.put("level", row.getCell(6).getStringCellValue());
                        break;
                    case "SubcontractorBean":
                        setExcleTString(7, row, 0);
                        if (row.getCell(1) != null)
                            obj.put("personName", row.getCell(1).getStringCellValue());
                        if (row.getCell(2) != null)
                            obj.put("sex", row.getCell(2).getStringCellValue());
                        if (row.getCell(3) != null)
                            obj.put("nation", row.getCell(3).getStringCellValue());
                        if (row.getCell(4) != null)
                            obj.put("id", row.getCell(4).getStringCellValue());
                        if (row.getCell(5) != null)
                            obj.put("certificate", row.getCell(5).getStringCellValue());
                        if (row.getCell(6) != null)
                            obj.put("level", row.getCell(6).getStringCellValue());
                        break;
                    case "SelfOwnedBean":
                        setExcleTString(7, row, 0);
                        if (row.getCell(1) != null)
                            obj.put("personName", row.getCell(1).getStringCellValue());
                        if (row.getCell(2) != null)
                            obj.put("sex", row.getCell(2).getStringCellValue());
                        if (row.getCell(3) != null)
                            obj.put("nation", row.getCell(3).getStringCellValue());
                        if (row.getCell(4) != null)
                            obj.put("id", row.getCell(4).getStringCellValue());
                        if (row.getCell(5) != null)
                            obj.put("certificate", row.getCell(5).getStringCellValue());
                        if (row.getCell(6) != null)
                            obj.put("level", row.getCell(6).getStringCellValue());
                        break;
                    case "ProjectBean":
                        setExcleTString(7, row, 0);
                        if (row.getCell(1) != null)
                            obj.put("toolsProcesName", row.getCell(1).getStringCellValue());
                        if (row.getCell(2) != null)
                            obj.put("toolsName", row.getCell(2).getStringCellValue());
                        if (row.getCell(3) != null)
                            obj.put("toolsModel", row.getCell(3).getStringCellValue());
                        if (row.getCell(4) != null)
                            obj.put("toolsUnit", row.getCell(4).getStringCellValue());
                        if (row.getCell(5) != null)
                            obj.put("toolsNum", row.getCell(5).getStringCellValue());
                        if (row.getCell(6) != null)
                            obj.put("notes", row.getCell(6).getStringCellValue());
                        break;
                    case "TowerProjectBean":
                        setExcleTString(4, row, 0);
                        if (row.getCell(1) != null)
                            obj.put("towerName", row.getCell(1).getStringCellValue());
                        if (row.getCell(2) != null)
                            obj.put("geodeticLon", row.getCell(2).getStringCellValue());
                        if (row.getCell(3) != null)
                            obj.put("geodeticLat", row.getCell(3).getStringCellValue());
                        break;
                    default:
                        break;
                }
                list.add(obj);
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
            throw new RuntimeException("模板中含有单元格数据格式不正确");
        }
        return list;
    }


    /**
     *       * 获取图片和位置 (xlsx)
     *       * @param sheet
     *       * @return
     *       * @throws IOException
     */
    public static Map<String, PictureData> getPicturesXlsx(XSSFSheet sheet, String className) throws IOException {
        int i = 0;
        Map<String, PictureData> map = new HashMap<String, PictureData>(100);

        List<POIXMLDocumentPart> list = sheet.getRelations();
        for (POIXMLDocumentPart part : list) {
            if (part instanceof XSSFDrawing) {
                XSSFDrawing drawing = (XSSFDrawing) part;
                List<XSSFShape> shapes = drawing.getShapes();

                for (XSSFShape shape : shapes) {
                    XSSFPicture picture = (XSSFPicture) shape;
                    XSSFClientAnchor anchor = picture.getPreferredSize();
                    CTMarker marker = anchor.getFrom();
                    Row row = sheet.getRow(marker.getRow());
                    if (row == null) continue;
                    // System.out.println(row.getCell(16));
                    String key = null;
                    switch (className) {
                        case "SysOrg":
                            key = setKey(picture, row, "SysOrg");
                            break;
                        case "SysOrgWorker":
                            key = setKey(picture, row, "SysOrgWorker");
                            break;
                        case "BmWorker":
                            key = setKey(picture, row, "BmWorker");
                            break;
                        case "BmProjectWorker":
                            key = setKey(picture, row, "BmProjectWorker");
                            break;
                        case "BmConstruction":
                            key = setKey(picture, row, "BmConstruction");
                            break;
                        case "BmWorkerCertificate":
                            key = setKey(picture, row, "BmWorkerCertificate");
                            break;
                        case "BmWorkerPolicy":
                            key = setKey(picture, row, "BmWorkerPolicy");
                            break;
                        case "BmProjectWorkerBl":
                            key = setKey(picture, row, "BmProjectWorkerBl");
                            break;
                        default:
                            key = "";
                            break;
                    }
                    map.put(key, picture.getPictureData());
                }
            }
        }


        return map;
    }

    /**
     * 图片写出
     * @param mapData  mapData
     * @param className mapData
     * @return list
     * @throws IOException
     */
    public static List<String> writeImg(Map<String, PictureData> mapData, String className) throws IOException {
        if (mapData == null || mapData.size() == 0) return new ArrayList<>();
        Object[] key = mapData.keySet().toArray();
        ArrayList<String> filename = new ArrayList<>();
        for (int i = 0; i < mapData.size(); i++) {
//    		 获取图片流  
            PictureData pic = mapData.get(key[i]);
//    		 获取图片索引  
            String picName = key[i].toString();
//    		 获取图片格式  
//    		String ext = pic.suggestFileExtension();
            byte[] data = pic.getData();
            String picPath = null;
            String path = null;
            switch (className) {
                case "SysOrg":
                    picPath = "";
                    break;
                default:
                    break;
            }
//    		图片保存路径
            File file = new File(picPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            FileOutputStream out = new FileOutputStream(picPath + picName + ".jpg");
            out.write(data);
            out.flush();
            System.out.println(picPath + picName + ".jpg");
            out.close();
            filename.add(picName);
        }
        return filename;
    }


    private static String setKey(XSSFPicture picture, Row row, String className) {
        if (row == null) return null;
        String result = picture.getPreferredSize().toString();
        String pattern = "\\<xdr\\:col\\>[1-9]\\d*\\<\\/xdr\\:col\\>";
        Pattern r = Pattern.compile(pattern);
        String col = "";
        Matcher m = r.matcher(result);
        if (m.find()) {
            col = m.group(0);
        } else {
            System.out.println("NO MATCH");
        }

        switch (className) {
            case "SysOrg":
                switch (col) {
                    case "<xdr:col>11</xdr:col>":
                        return "SysOrg" + row.getCell(3).getStringCellValue() + "YYZZ";
                    case "<xdr:col>14</xdr:col>":
                        return "SysOrg" + row.getCell(3).getStringCellValue() + "JZQYZZZ";
                    case "<xdr:col>17</xdr:col>":
                        return "SysOrg" + row.getCell(3).getStringCellValue() + "CZXSDLSSXKZ";
                    case "<xdr:col>21</xdr:col>":
                        return "SysOrg" + row.getCell(3).getStringCellValue() + "AQSCXKZ";
                }
                break;
            case "BmWorkerCertificate":
                return row.getCell(5).getStringCellValue();
            case "BmWorkerPolicy":
                return row.getCell(3).getStringCellValue();
            default:
                return "";

        }

        return null;
    }

    private static void setExcleTString(int j, Row row, int r) {
        for (int i = 0; i < j; i++) {
            if (row.getCell(i) != null && i != r) {
                row.getCell(i).setCellType(CellType.STRING);
            } else {
            }
        }
    }

    /**
     *
     * @param j
     * @param row
     * @param r
     * @param k 某列为时间  所传列数
     */
    private static void setExcleTString(int j, Row row, int r,int k) {
        for (int i = 0; i < j; i++) {
            if (row.getCell(i) != null && i != r) {
                if(i != k){
                    row.getCell(i).setCellType(CellType.STRING);
                }else{
                    try{
                        row.getCell(k).setCellType(CellType.NUMERIC);
                    }catch (IllegalStateException e){
                        row.getCell(i).setCellType(CellType.STRING);
                    }
                }
            }
        }
    }

    private static void setExcleTDate(int j, Row row, int r) {
        row.getCell(j).setCellType(CellType.NUMERIC);
    }
}
