package com.system.utils;

import com.system.transfer.configure.TableStructureCreateInVo;
import com.system.transfer.configure.TableStructureCreateInVoRecords;
import com.system.transfer.configure.TableStructureDataOutVoRecords;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Inori
 */
public class TableStructureUtil {

    private final static String CONFIG = "{\"size\":\"default\",\"hideRequiredAsterisk\":false,\"labelWidth\":100,\"labelPosition\":\"right\",\"dbTableComment\":\"\",\"dbTableName\":\"\"}";

    private final static String FIELD = "{\"label\":\"\",\"type\":\"input\",\"options\":{\"width\":\"100%\",\"defaultValue\":\"\",\"placeholder\":\"\",\"maxlength\":null,\"prefix\":\"\",\"suffix\":\"\",\"prepend\":\"\",\"append\":\"\",\"disabled\":false,\"clearable\":false,\"readonly\":false,\"rules\":{\"trigger\":\"blur\",\"enum\":\"\",\"message\":\"\",\"pattern\":\"\",\"required\":false,\"type\":\"any\"}},\"key\":\"\",\"model\":\"\",\"rules\":[],\"dbFieldName\":\"\",\"dbFieldComment\":\"\"}";


    public static String getFormGenerator(String sFormId, String name, String kingdeeFiledDetail) {
        Map<String, Object> result = new LinkedHashMap<>();

        Map<String, Object> temp01 = JsonUtil.toMap(CONFIG, String.class, Object.class);
        temp01.put("formId", sFormId);
        temp01.put("dbTableName", sFormId.toLowerCase());
        temp01.put("dbTableComment", name);
        result.put("config", temp01);

        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> temp02 = JsonUtil.toMap(FIELD, String.class, Object.class);
        temp02.put("label", "唯一标识");
        temp02.put("key", UUID.randomUUID().toString().replace("-", ""));
        temp02.put("model", "queue_id");
        temp02.put("dbFieldName", "queue_id");
        temp02.put("dbFieldComment", "唯一标识");
        list.add(temp02);

        List<Object> tempList = JsonUtil.toList(kingdeeFiledDetail, Object.class);
        for (Object object : tempList) {
            Map<String, Object> map = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);

            Map<String, Object> temp03 = JsonUtil.toMap(FIELD, String.class, Object.class);
            temp03.put("label", map.get("mesName"));
            temp03.put("key", UUID.randomUUID().toString().replace("-", ""));
            temp03.put("model", map.get("thirdPartyField"));
            temp03.put("dbFieldName", map.get("thirdPartyField"));
            temp03.put("dbFieldComment", map.get("mesName"));
            list.add(temp03);
        }

        result.put("list", list);
        return JsonUtil.toString(result);
    }

    public static List<TableStructureCreateInVoRecords> getFieldListBySyn(String kingdeeFiledDetail) {
        List<TableStructureCreateInVoRecords> recordsList = new ArrayList<>();

        List<Object> tempList = JsonUtil.toList(kingdeeFiledDetail, Object.class);
        for (Object object : tempList) {
            Map<String, Object> map = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);

            TableStructureCreateInVoRecords records = new TableStructureCreateInVoRecords();
            records.setDbFieldName((String) map.get("thirdPartyField"));
            records.setDbFieldType(getDbFieldTypeBySyn((String) map.get("type")));
            records.setDbFieldDefault("NULL");
            records.setDbFieldComment("'" + map.get("mesName") + "'");

            recordsList.add(records);
        }

        return recordsList;
    }

    private static String getDbFieldTypeBySyn(String fieldType) {
        switch (fieldType) {
            case "数值":
                return "INT(11)";
            case "精确数值":
                return "DECIMAL(10, 2)";
            default:
                return "VARCHAR(255)";
        }
    }

    public static TableStructureCreateInVo purchaseInVo(TableStructureCreateInVo inVo) {
        Map<String, Object> map = JsonUtil.toMap(inVo.getFormJson(), String.class, Object.class);

        Map<String, Object> configMap = JsonUtil.toMap(JsonUtil.toString(map.get("config")), String.class, Object.class);
        inVo.setFormId((String) configMap.get("formId"));
        inVo.setDbTableName((String) configMap.get("dbTableName"));
        inVo.setDbTableComment((String) configMap.get("dbTableComment"));
        return inVo;
    }

    public static List<TableStructureCreateInVoRecords> getFieldList(String json) {
        List<TableStructureCreateInVoRecords> recordsList = new ArrayList<>();

        Map<String, Object> map = JsonUtil.toMap(json, String.class, Object.class);

        String listJson = JsonUtil.toString(map.get("list"));
        List<Object> objectList = JsonUtil.toList(listJson, Object.class);
        for (Object object : objectList) {
            TableStructureCreateInVoRecords records = new TableStructureCreateInVoRecords();

            Map<String, Object> listMap = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);

            records.setKey((String) listMap.get("key"));
            records.setDbFieldName((String) listMap.get("dbFieldName"));
            records.setDbFieldType(getDbFieldType((String) listMap.get("type")));
            records.setDbFieldDefault("NULL");
            records.setDbFieldComment("'" + listMap.get("dbFieldComment") + "'");

            recordsList.add(records);
        }

        return recordsList;
    }

    private static String getDbFieldType(String fieldType) {
        String result;
        switch (fieldType) {
            case "input":
            case "text":
            case "password":
                result = "VARCHAR(128)";
                break;
            case "textarea":
                result = "TEXT";
                break;
            case "richtext-editor":
                result = "LONGTEXT";
                break;
            case "switch":
                result = "TINYINT(1)";
                break;
            default:
                result = "VARCHAR(255)";
        }
        return result;
    }

    public static List<TableStructureDataOutVoRecords> getFormFieldList(String json) {
        List<TableStructureDataOutVoRecords> recordsList = new ArrayList<>();

        Map<String, Object> map = JsonUtil.toMap(json, String.class, Object.class);

        String listJson = JsonUtil.toString(map.get("list"));
        List<Object> objectList = JsonUtil.toList(listJson, Object.class);
        for (Object object : objectList) {
            TableStructureDataOutVoRecords records = new TableStructureDataOutVoRecords();

            Map<String, Object> listMap = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);
            records.setKey((String) listMap.get("dbFieldName"));
            records.setFieldName((String) listMap.get("dbFieldComment"));
            recordsList.add(records);
        }

        return recordsList;
    }

    public static Map<String, String> getDbFieldName(Object data) {
        Map<String, String> result = new HashMap<>(10);

        Map<String, Object> map = JsonUtil.toMap(JsonUtil.toString(data), String.class, Object.class);

        String listJson = JsonUtil.toString(map.get("list"));
        List<Object> objectList = JsonUtil.toList(listJson, Object.class);
        for (Object object : objectList) {
            Map<String, Object> listMap = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);

            result.put((String) listMap.get("model"), (String) listMap.get("dbFieldName"));
        }

        return result;
    }

    public static List<String> getDbFieldNameList(Object data) {
        List<String> result = new ArrayList<>();

        Map<String, Object> map = JsonUtil.toMap(JsonUtil.toString(data), String.class, Object.class);

        String listJson = JsonUtil.toString(map.get("list"));
        List<Object> objectList = JsonUtil.toList(listJson, Object.class);
        for (Object object : objectList) {
            Map<String, Object> listMap = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);

            result.add((String) listMap.get("dbFieldName"));
        }

        return result;
    }

    public static Map<String, Object> getLabelMap(Object data, Map<String, Object> temp) {
        Map<String, Object> result = new HashMap<>(10);

        Map<String, Object> map = JsonUtil.toMap(JsonUtil.toString(data), String.class, Object.class);

        String listJson = JsonUtil.toString(map.get("list"));
        List<Object> objectList = JsonUtil.toList(listJson, Object.class);
        for (Object object : objectList) {
            Map<String, Object> listMap = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);

            result.put((String) listMap.get("label"), temp.get(String.valueOf(listMap.get("dbFieldName"))));
        }

        return result;
    }

    public static Map<String, Object> getModelMap(Object data, Map<String, Object> temp) {
        Map<String, Object> map = JsonUtil.toMap(JsonUtil.toString(data), String.class, Object.class);

        Map<String, Object> result = new HashMap<>(10);
        String listJson = JsonUtil.toString(map.get("list"));
        List<Object> objectList = JsonUtil.toList(listJson, Object.class);
        for (Object object : objectList) {
            Map<String, Object> listMap = JsonUtil.toMap(JsonUtil.toString(object), String.class, Object.class);

            result.put((String) listMap.get("model"), temp.get(String.valueOf(listMap.get("dbFieldName"))));
        }

        return result;
    }

    public static List<TableStructureCreateInVoRecords> isCreateOrDelete(List<TableStructureCreateInVoRecords> temp01List, List<TableStructureCreateInVoRecords> temp02List) {
        return temp01List.stream().filter(m ->
                !temp02List.stream().map(TableStructureCreateInVoRecords::getKey).collect(Collectors.toList()).contains(m.getKey()))
                .collect(Collectors.toList());
    }

    public static List<TableStructureCreateInVoRecords> isUpdate(List<TableStructureCreateInVoRecords> temp01List, List<TableStructureCreateInVoRecords> temp02List) {
        List<String> keyList = temp01List.stream()
                .filter(m -> temp02List.stream().map(TableStructureCreateInVoRecords::getKey).collect(Collectors.toList()).contains(m.getKey()))
                .map(TableStructureCreateInVoRecords::getKey)
                .collect(Collectors.toList());

        List<TableStructureCreateInVoRecords> result = new ArrayList<>();
        for (String key : keyList) {
            TableStructureCreateInVoRecords records01 = temp01List.stream().filter(m -> key.equals(m.getKey())).findFirst().orElse(new TableStructureCreateInVoRecords());

            TableStructureCreateInVoRecords records02 = temp02List.stream().filter(m -> key.equals(m.getKey())).findFirst().orElse(new TableStructureCreateInVoRecords());

            records01.setOldDbFileName(records02.getDbFieldName());
            if (!records01.getDbFieldName().equals(records02.getDbFieldName())) {
                result.add(records01);
            }
            if (!records01.getDbFieldType().equals(records02.getDbFieldType())) {
                result.add(records01);
            }
            if (!records01.getDbFieldComment().equals(records02.getDbFieldComment())) {
                result.add(records01);
            }
        }

        return result;
    }


}
