package com.brilliance.isc.dsp.service.impl;

import com.brilliance.isc.dsp.model.*;
import com.brilliance.isc.dsp.service.FrameService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author weiguanying .
 * @date 2023/2/20
 * @description dsp file parse service.
 */
@Service
public class FrameServiceImpl implements FrameService {

    //匹配空格之外的字符或者双引号内的内容
    static Pattern pattern = Pattern.compile("[^\\s\"]+|\"[^\"]*\"");


    public static class KV {
        int index;

        public KV(StringBuffer components, int index, List<StringBuffer> fieldValues) {
            this.index = index;
            this.components = components;
            this.fieldValues = fieldValues;
        }

        StringBuffer components;
        List<StringBuffer> fieldValues;


        public int getIndex() {
            return index;
        }

        public StringBuffer getComponents() {
            return components;
        }

        public List<StringBuffer> getFieldValues() {
            return fieldValues;
        }
    }

    /**
     * 获取数组下标
     *
     * @param lines
     * @param pos
     * @return
     */
    protected String getLineField(String[] lines, int pos) {
        if (lines.length >= pos + 1) {
            return lines[pos];
        }
        return "";
    }

    /**
     * 字符串拆分成数组
     *
     * @param line
     * @return
     */
    public static String[] splitLine(String line) {
        line = line.trim();// 原处理是trimStart
        return line.split("(?<!(\\{)[^}]{0,1000})\\s+(?=[^}]*(\\{|$))");
    }

    /**
     * 根据特定字符串截取名称
     *
     * @param line 一行字符串数据
     * @return "\u001F" 中间的字符串
     * @author weiguanying
     */
    public static String valueString(String line) {
        String value = line.substring(line.indexOf("\u001F") + 1, line.lastIndexOf("\u001F"));
        return value;
    }

    /**
     * 获取 String [] 最后几个数组
     *
     * @param str
     * @param total
     * @return
     * @author weiguanying
     */
    public static String[] subStr(String[] str, int total) {
        String[] newStr = new String[total];
        for (int i = 0; i < total; i++) {
            newStr[i] = str[str.length - (total - i)];
        }
        return newStr;
    }

    @Override
    public HashMap<String, Object> printEibsElement(String content) {
        String[] fields;
        StringBuffer writeLine = new StringBuffer("");  // 最终返回字符串
        fields = splitLine(content);
        String fieldName = getLineField(fields, 0).toLowerCase().trim();
        String fieldType = getLineField(fields, 1);
        HashMap<String, Object> map = new HashMap<>();
        if ("ff".equals(fieldName)) {
            if (fieldType.equals("16") || fieldType.equals("5")) {
            }// GridView暂时不处理
            String field = "field";
            String fieldPositionX = "";
            String fieldPositionY = "";
            String fieldWidth = "0";
            String fieldHeight = "0";
            String fieldVisible = ""; // 1-visible
            String fieldReadonly = ""; // 1-readonly
            String fieldMandatory = ""; // 1-mandatory
            String fieldCheckValue = ""; // 1-checkvalue
            String fieldIndependent = ""; // 1-independent
            String fieldTabGroup = ""; // 1-tabgroup
            String fieldShowKey = ""; // 1-showkey

            fieldPositionX = getLineField(fields, 2);
            fieldPositionY = getLineField(fields, 3);
            fieldWidth = getLineField(fields, 4);
            fieldHeight = getLineField(fields, 5);
            fieldVisible = getLineField(fields, 6); // 1-visible
            fieldReadonly = getLineField(fields, 7); // 1-readonly
            fieldMandatory = getLineField(fields, 8); // 1-mandatory
            fieldCheckValue = getLineField(fields, 9); // 1-
            if (("1").equals(fieldType)) {
                fieldCheckValue = getLineField(fields, 11); // 1-
            }
            if (("3").equals(fieldType)) {
                fieldCheckValue = getLineField(fields, 10); // 1-
            }
            fieldIndependent = getLineField(fields, 10); // 1-independent
            fieldTabGroup = getLineField(fields, 11); // 1-tabgroup
            fieldShowKey = getLineField(fields, 12); // 1-showkey

            FrameField frameField = new FrameField();
            frameField.setLeft(fieldPositionX);
            frameField.setTop(fieldPositionY);
            frameField.setWidth(fieldWidth);
            frameField.setHeight(fieldHeight);
            frameField.setVisible(fieldVisible);
            frameField.setReadonly(fieldReadonly);
            frameField.setMandatory(fieldMandatory);
            frameField.setCheckvalue(fieldCheckValue);
            switch (fieldType) {
                case "1": {
                    frameField.setViewType("Block");
                    break;
                }
                case "2": {
                    frameField.setViewType("Combobox");
                    break;
                }
                case "3": {
                    frameField.setViewType("Checkbox");
                    break;
                }
                case "0": {
                    frameField.setViewType("Input");
                    break;
                }
                case "5": {
                    frameField.setViewType("Label");
                    break;
                }
                case "6": {
                    frameField.setViewType("Button");
                    break;
                }
                case "7": {
                    frameField.setViewType("Date");
                    break;
                }
                case "8": {
                    frameField.setViewType("Amount");
                    break;
                }
                case "10": {
                    frameField.setViewType("Table");
                    break;
                }
                case "11": {
                    frameField.setViewType("Block");
                    break;
                }
                //Text Difference vs. System
                case "12": {
                    frameField.setViewType("Block");
                    break;
                }
                case "14": {
                    frameField.setViewType("Password");
                    break;
                }
                case "17": {
                    frameField.setViewType("Composite");
                    break;
                }
                case "19": {
                    frameField.setViewType("Multipart");
                    break;
                }
            }
            if (fieldReadonly.equals("1")) {
                frameField.setEnabled("false");
            }

            if (fieldMandatory.equals("1")) {
                frameField.setEnabled("true");
            }
            //组合框字体标红（倒数第2列为0时）
            if ("Input".equals(frameField.getViewType()) || "Combobox".equals(frameField.getViewType())) {
                if ("0".equals(fields[fields.length - 2])) {
                    frameField.setIsRedCode("Y");
                }
            }
            map.put("FrameField", frameField);
        } else if ("lb".equals(fieldName)) {
            Label label = new Label();
            String fieldText = valueString(content);//  getLineField(fields, 1).trim();
            String fieldWidth = "75";
            String fieldHeight = "22";
            String[] newStr = subStr(fields, 4);
            String fieldPositionX = getLineField(newStr, 0);
            String fieldPositionY = getLineField(newStr, 1);
            //String fieldHeight = getLineField(newStr, 2);
            //String fieldWidth = getLineField(newStr, 3);

            label.setHeight(fieldHeight);
            label.setWidth(fieldWidth);
            label.setValue(fieldText);
            label.setLeft(fieldPositionX);
            label.setTop(fieldPositionY);
            map.put("Label", label);
        } else if ("fp".equals(fieldName)) {
            String[] newStr = subStr(fields, 4);
            String fieldText = valueString(content);//  getLineField(fields, 1).trim();
            String fieldPositionX = getLineField(newStr, 0);
            String fieldPositionY = getLineField(newStr, 1);
            String fieldHeight = getLineField(newStr, 2);
            String fieldWidth = getLineField(newStr, 3);
            Panel panel = new Panel();
            panel.setName(fieldText);
            panel.setWidth(fieldWidth);
            panel.setHeight(fieldHeight);

            map.put("FramePanel", panel);
        } else if ("grid".equals(fieldName)) {
            Grid grid = new Grid();
            grid.setRows(getLineField(fields, 1));
            grid.setColumns(getLineField(fields, 2));
            map.put("Grid", grid);
        } else if ("gc".equals(fieldName)) {
            GridLists lists = new GridLists();
            lists.setColumn(getLineField(fields, 1));
            lists.setWidth(getLineField(fields, 2));
            map.put("GridLists", lists);
        } else if ("gv".equals(fieldName)) {
            GridValue gridValue = new GridValue();
            String fieldText = valueString(content);//  getLineField(fields, 1).trim();
            gridValue.setValue(fieldText);
            gridValue.setColumn(getLineField(fields, 2));
            gridValue.setRow(getLineField(fields, 1));
            String[] newStr = subStr(fields, 6);
            gridValue.setIsRedLine("0".equals(getLineField(newStr, 4)) ? "1" : "0");//表格存在绿色
            //表格中第5列为类型，值3:Checkbox
            fieldType = getLineField(fields, 4);
            //eg:GV 3 2 31.07.2024 7 1 0 0 -1 1(一期是多为9列的)单选框排除
            if (10 == fields.length && !"3".equals(fieldType)) {
                gridValue.setIsRedLine(fields[9]);//1红色2绿色
            }
            if ("3".equals(fieldType)) {
                gridValue.setViewType("Checkbox");
            }
            gridValue.setIsButton("6".equals(getLineField(newStr, 0)) ? "Y" : "N");

            map.put("GridValue", gridValue);
            return map;

        } else if ("va".equals(fieldName) && !content.contains("\\t")) {
            FrameField frameField = new FrameField();
            //frameField.setValue(getLineField(fields, 1));
            frameField.setValue(content.replaceFirst("VA \u001F", ""));
            map.put("FieldValue", frameField);
        } else if (("pv".equals(fieldName) && needHandlePv(fields)) || ("va".equals(fieldName) && content.contains("\\t"))) {
            //对于PV 类型的当表格处理，具体数据在Va中，用制表符分隔
            if ("va".equals(fieldName)){
                String[] splitTableData = content.substring(4).replace("\\t\\t","\\tnone\\t").split("\\\\t");
                List<GridValue> list = new ArrayList<GridValue>();
                for (int i = 0; i < splitTableData.length; i++) {
                    GridValue gridValue = new GridValue();
                    gridValue.setValue(splitTableData[i].replace("none","").replace("000\\\\n","").replace("0\\\\n","").replace("\\\\n",""));
                    gridValue.setRow("1");
                    gridValue.setTableColumnIndex(String.valueOf(i));
                    list.add(gridValue);
                }
                map.put("GridValues", list);
                return map;
            }

            // pv表格重新解析
            fields = spitPvData(content).toArray(new String[0]);
            GridValue gridValue = parsePvToGv(content, fields);
            //表头增加外框
            if ("1".equals(getLineField(fields, 2))) {
                Grid grid = new Grid();
                map.put("Grid", grid);
            }
            map.put("GridValue", gridValue);
        }else if ("cp".equals(fieldName)){
            //单选框的描述
            FrameField frameField = new FrameField();
            frameField.setValue(content.substring(4));
            map.put("FrameFieldCheckbox", frameField);
        }
        return map;
    }

    private GridValue parsePvToGv(String content, String[] fields) {
        GridValue gridValue = new GridValue();
        gridValue.setValue(getLineField(fields, 3));
        gridValue.setColumn(String.valueOf(Integer.parseInt(getLineField(fields, 2)) - 1));
        gridValue.setRow("0");
        gridValue.setWidth(getLineField(fields, 4));
        //Va数据的index
        gridValue.setTableColumnIndex(getLineField(fields, 1).substring(1));
        return gridValue;
    }

    private boolean needHandlePv(String[] fields){
        boolean flg = false;
        if (fields.length == 1) {
            return flg;
        }
        try {
            Integer.parseInt(getLineField(fields, 1).substring(1));
            Integer.parseInt(getLineField(fields, 2));
            flg = true;
        } catch (Exception e) {
        }
        return flg;
    }

    public static List<String>  spitPvData(String content){
        Matcher matcher = pattern.matcher(content);
        List<String> list = new ArrayList<>();
        while (matcher.find()) {
            list.add(matcher.group().replace("\"", ""));
        }
        return list;
    }


}

