package com.brilliance.isc.swift.swifteditor.tag.message;

import com.brilliance.isc.common.util.StringUtils;
import com.brilliance.isc.swift.swifteditor.tag.TagFormat;
import com.brilliance.isc.swift.swifteditor.tag.TagLine;
import com.google.gson.Gson;
import org.apache.poi.ss.usermodel.Cell;
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.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;


public class MessageFormat {
    private static final String MT_PATTERN = "swift/swift_pattern_2020.xlsx";
    public static Map<String, SWFMessage> mtCache = new HashMap<String, SWFMessage>();
    public static Gson gson = new Gson();

    static {
        loadSWFMessage();
    }

    public static SWFMessage getSWFMessage(String mtType) {
        if(StringUtils.isEmpty(mtType)){
            return null;
        }
        SWFMessage swfmsg = mtCache.get(mtType);

        if (swfmsg == null && mtType.charAt(1) == '9')
            swfmsg = mtCache.get('n' + mtType.substring(1));
        if (swfmsg == null) {
            mtType = mtType.toUpperCase();
            swfmsg = mtCache.get(mtType);
        }
        if (swfmsg != null) {
            swfmsg.setMtType(mtType);
            return swfmsg.clone();
        }
        return null;
    }

    public static void loadSWFMessage() {
        InputStream ins = MessageFormat.class.getClassLoader().getResourceAsStream(MT_PATTERN);

        try {
            @SuppressWarnings("resource")
            XSSFWorkbook workBook = new XSSFWorkbook(ins);
            int sheetCount = workBook.getNumberOfSheets();
            for (int i = 0; i < sheetCount; i++) {
                Sheet sheet = workBook.getSheetAt(i);
                loadSingleSWFSheet(sheet);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private static void loadSingleSWFSheet(Sheet sheet) {
        //System.out.println(sheet.getSheetName());
        //获得当前sheet的开始行
        int firstRowNum = sheet.getFirstRowNum();
        //获得当前sheet的结束行
        int lastRowNum = sheet.getLastRowNum();
        // 定义一个栈结构，用来指示当前处理对象层级结构
        Stack<MessageArea> stack = new Stack<MessageArea>();
        SWFMessage message = new SWFMessage();
        message.setMtType(sheet.getSheetName());
        mtCache.put(sheet.getSheetName(), message);
        stack.add(message);
        int lastTno = 0;
        rowBegin:
        for (int i = firstRowNum; i <= lastRowNum; i++) {
            Row row = sheet.getRow(i);
            if (row == null)
                continue;
            //获得当前行的开始列
            int firstCellNum = row.getFirstCellNum();
            if(firstCellNum < 0)
                continue ;
            //获得当前行的列数
            int lastCellNum = row.getPhysicalNumberOfCells();

            for (int j = 0; j <= lastCellNum - firstCellNum; j++) {
                Cell cell = row.getCell(j + firstCellNum);

                String cellValue = getCellValue(cell).trim();
                if (j == 0) {
                    if (cellValue.length() == 0) //空行
                        continue rowBegin;
                    if (cellValue.matches("O|M")) {
                        String tagName = getCellValue(row.getCell(j + firstCellNum + 1));
                        String desp = getCellValue(row.getCell(j + firstCellNum + 2));
                        String tno = getCellValue(row.getCell(j + firstCellNum + 4)).replaceAll("\\D", "");
                        String pattern = getCellValue(row.getCell(j + firstCellNum + 3));

                        TagLine tagLine = TagFormat.getTagLine(tagName);  //一行tag
                        tagLine.setStatus(cellValue);
                        tagLine.setDesp(desp);
                        try {
                            tagLine.setTno(Integer.parseInt(tno));
                            lastTno = tagLine.getTno();
                        } catch (Exception e) {
                            System.out.println(Integer.valueOf(tno.charAt(0)));
                        }
                        tagLine.setName(tagName);

                        if (tagName.endsWith("a") && pattern.contains(" or ")) {
                            tagName = tagName.substring(0, tagName.length() - 1);
                            String[] sube = pattern.split(",|or");
                            //String[] tagSuffix = new String[sube.length];
                            List<String> tagSuffix = new ArrayList<String>();
                            boolean hasNoLetter = false;
                            for (int m = 0; m < sube.length; m++) {
                                if (sube[m].trim().length() == 0)
                                    continue;
                                if (!hasNoLetter && sube[m].contains("No") && sube[m].contains("letter") && sube[m].contains("option")) {
                                    tagSuffix.add(tagName);
                                    hasNoLetter = true;
                                    continue;
                                }

                                tagSuffix.add(tagName + sube[m].trim());
                            }

                            tagLine.setSuffix(tagSuffix);
                        }
                        stack.peek().addSubArea(tagLine);
                        if (stack.peek().getType() == MessageArea.CYC || stack.peek().getType() == MessageArea.SEQ) {
                            if (((AbstractMessageArea) stack.peek()).begNo > tagLine.getTno()) {
                                ((AbstractMessageArea) stack.peek()).begNo = tagLine.getTno();
                            }
                            if (((AbstractMessageArea) stack.peek()).endNo < tagLine.getTno()) {
                                ((AbstractMessageArea) stack.peek()).endNo = tagLine.getTno();
                            }
                        }

                        continue rowBegin;
                    } else if (cellValue.matches("[\\-]{1,}\\>")) //循环开发
                    {
                        //循环开始
                        CYCList cycLst = new CYCList();
                        cycLst.setName((lastTno + 1) + "");
                        CYC cyc = new CYC();
                        cycLst.addSubArea(cyc);
                        cycLst.setPattern(cyc);
                        stack.peek().addSubArea(cycLst);
                        stack.push(cyc);
                        continue rowBegin;
                    } else if (cellValue.matches("[\\-]{1,}\\|")) //循环结束
                    {
                        //循环结束
                        stack.pop();
                        continue rowBegin;
                    } else if (cellValue.indexOf("End of") >= 0) //序列接收
                    {
                        //循环结束
                        stack.pop();
                        continue rowBegin;
                    }
                    int idx0 = cellValue.indexOf("Sequence");
                    int idx1 = cellValue.indexOf("Subsequence");

                    if (idx0 >= 0 || idx1 >= 0) //序列开始
                    {
                        SEQList seqlst = new SEQList();
                        //判断是否有循环
                        if (cellValue.indexOf("Repetitive") >= 0)
                            seqlst.setCyc(1);
                        else
                            seqlst.setCyc(0);
                        //判断是否必填
                        if (cellValue.indexOf("Mandatory") >= 0)
                            seqlst.setOm("M");
                        else
                            seqlst.setOm("O");
                        //取出名字
                        int idx = 0;
                        if (idx0 >= 0)
                            idx = idx0 + "Sequence".length();
                        if (idx1 >= 0)
                            idx = idx1 + "Subsequence".length();
                        String name = "";
                        while (idx < cellValue.length()) {
                            char c = cellValue.charAt(idx);
                            if (c >= 'a' && c <= 'z' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')) {
                                name = name + c;
                            } else {
                                if (name.length() != 0)
                                    break;
                            }
                            idx++;
                        }
                        seqlst.setName(name);
                        SEQ seq = new SEQ();
                        seqlst.addSubArea(seq);
                        seqlst.setPattern(seq);
                        seqlst.setDesp(cellValue);
                        stack.peek().addSubArea(seqlst);
                        stack.push(seq);
                        continue rowBegin;
                    } else //标题
                    {
                        if (message.getName() == null)
                            message.setName(cellValue.replaceAll("\\u00A0"," "));
                    }
                }
                //System.out.print(cellValue);
            }
            //System.out.print("\r\n");
        }
        message.setAnlyReg(MessageAnalyzer.generReg(message));
    }

    private static String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }
        //把数字当成String来读，避免出现1读成1.0的情况
        if (cell.getCellType() == CellType.NUMERIC) {
            cell.setCellType(CellType.STRING);
        }
        //判断数据的类型
        switch (cell.getCellType()) {
            case NUMERIC: //数字
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case STRING: //字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case BOOLEAN: //Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA: //公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case BLANK: //空值
                cellValue = "";
                break;
            case ERROR: //故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue.replace((char) 12288, ' ').trim();
    }
}
