package cn.edu.whu.boot.common.utils.collection;

import cn.edu.whu.boot.allocation.controllers.dtos.Pair;
import cn.edu.whu.boot.common.domain.CommonConstant;
import cn.edu.whu.boot.xml.xmlreader.bean.Field;
import cn.edu.whu.boot.xml.xmlreader.bean.Table;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.*;

/**
 * 该项目是以 XML 文件进行驱动运行! 而 cn.edu.whu.boot.xml.xmlreader.bean.Table 存放着 XML 配置的数据表!
 * 该类就是作为 Table 操作的工具类
 */
public class TableOperationUtil{

    /**
     * 获取 Table table 的 String fieldName 字段对应的值，若无该字段返回 null
     */
    public static Object getFieldValue(Table table, String fieldName){
        for(Map.Entry<String, Field> fieldEntry : table.getFields().entrySet()){
            Field field = fieldEntry.getValue();
            if(field.getKey().equals(fieldName)){
                return field.getValue();
            }
        }
        return null;
    }

    /**
     * 获取 Table table 的主键，若无主键返回 null
     */
    public static String getPrimaryKey(Table table){
        return getPrimaryKey(table.getFields());
    }

    public static String getPrimaryKey(Map<String, Field> map){
        if(map == null){
            return null;
        }
        for(Map.Entry<String, Field> fieldEntry : map.entrySet()){
            Field field = fieldEntry.getValue();
            if(field.isIdentity()){
                return field.getKey();
            }
        }
        return null;
    }
    public static String getParentID(Table table){
        return getParentID(table.getFields());
    }
    public static String getParentID(Map<String, Field> map){
        for(Map.Entry<String, Field> fieldEntry : map.entrySet()){
            Field field = fieldEntry.getValue();
            if(field.isParentID()){
                return field.getKey();
            }
        }
        return null;
    }

    /**
     * 获取 Table table 多媒体字段的字段名
     */
    public static String getCameraFieldName(Table table){
        for(Map.Entry<String, Field> fieldEntry : table.getFields().entrySet()){
            if((fieldEntry.getValue().getType() != null)
                    && CommonConstant.CAMERA.equals(fieldEntry.getValue().getType())){
                return fieldEntry.getKey();
            }
        }
        return null;
    }

    /**
     * 获取 Table table 空间字段的字段名
     */
    public static String getShapeFieldName(Table table){
        String geometryIsTrueFieldName = null;
        Map<String, Field> fields = table.getFields();
        for (Map.Entry<String, Field> fieldEntry : fields.entrySet()) {
            if (fieldEntry.getValue().isGeometry()) {
                geometryIsTrueFieldName = fieldEntry.getValue().getKey();
                break;
            }
        }
        return geometryIsTrueFieldName;
    }

    /**
     * 获取 Table table 多媒体字段的字段名
     */
    public static String getUploadNameFieldName(Table table){
        for(Map.Entry<String, Field> fieldEntry : table.getFields().entrySet()){
            if(fieldEntry.getValue().isUploadName()){
                return fieldEntry.getKey();
            }
        }
        return CommonConstant.FIX_FIELD_COLLECTOR;
    }

    /**
     * 如果存在关联表，关联表内容也是用 JsonString 来表示!
     * 因此需要调用该方法递归的解析 Table table
     */
    public static Table changeJsonObjectToField(Table table){
        Map<String, Field> fieldsMap = table.getFields();
        Set<String> fieldsKeySet = fieldsMap.keySet();
        Map<String, Field> newFieldsMap = new HashMap<>();
        for(String fieldKey : fieldsKeySet){
            Field field = fieldsMap.get(fieldKey);
            field = recursiveTraverseField(field);
            newFieldsMap.put(fieldKey, field);
        }
        table.setFields(newFieldsMap);
        return table;
    }

    private static Field recursiveTraverseField(Field field){
        if(field.getValue() == null || "".equals(field.getValue())){
            return field;
        }
        if((field.getAssociate() != null && !"".equals(field.getAssociate()))){
            List<Map<String, Field>> list = new ArrayList<>();
            Map<String, Field> map = new HashMap<>();
            JSONObject jsonObject = (JSONObject) field.getValue();
            Set<String> keySet = jsonObject.keySet();
            for(String key : keySet){
                Field parseField = JSON.toJavaObject(jsonObject.getJSONObject(key), Field.class);
                parseField = recursiveTraverseField(parseField);
                map.put(key, parseField);
            }
            list.add(map);
            field.setValue(list);
        }
        if((field.getCollection() != null && !"".equals(field.getCollection()))){
            List<Map<String, Field>> list = new ArrayList<>();
            JSONArray jsonArray = (JSONArray) field.getValue();
            for(Object object : jsonArray){
                Map<String, Field> map = new HashMap<>();
                JSONObject jsonObject = (JSONObject) object;
                Set<String> keySet = jsonObject.keySet();
                for(String key : keySet){
                    Field parseField = JSON.toJavaObject(jsonObject.getJSONObject(key), Field.class);
                    parseField = recursiveTraverseField(parseField);
                    map.put(key, parseField);
                }
                list.add(map);
            }
            field.setValue(list);
        }
        return field;
    }
//private static Field recursiveTraverseField(Field field){
//    if (field.getValue() == null || "".equals(field.getValue())) {
//        return field;
//    }
//
//    // 处理关联对象
//    if (field.getAssociate() != null && !"".equals(field.getAssociate())) {
//        if (!(field.getValue() instanceof JSONObject)) {
//            System.out.println("❌ 错误: 关联字段 " + field.getKey() + " 的值不是 JSONObject，而是: "
//                    + field.getValue().getClass().getName());
//            return field; // 跳过错误字段
//        }
//
//        List<Map<String, Field>> list = new ArrayList<>();
//        Map<String, Field> map = new HashMap<>();
//        JSONObject jsonObject = (JSONObject) field.getValue();
//        for (String key : jsonObject.keySet()) {
//            Field parseField = JSON.toJavaObject(jsonObject.getJSONObject(key), Field.class);
//            parseField = recursiveTraverseField(parseField);
//            map.put(key, parseField);
//        }
//        list.add(map);
//        field.setValue(list);
//    }
//
//    // 处理集合对象
//    if (field.getCollection() != null && !"".equals(field.getCollection())) {
//        if (!(field.getValue() instanceof JSONArray)) {
//            System.out.println("❌ 错误: 集合字段 " + field.getKey() + " 的值不是 JSONArray，而是: "
//                    + field.getValue().getClass().getName());
//            return field; // 跳过错误字段
//        }
//
//        List<Map<String, Field>> list = new ArrayList<>();
//        JSONArray jsonArray = (JSONArray) field.getValue();
//        for (Object object : jsonArray) {
//            Map<String, Field> map = new HashMap<>();
//
//            if (!(object instanceof JSONObject)) {
//                System.out.println("❌ 错误: 数组元素不是 JSONObject，而是: " + object.getClass().getName());
//                continue; // 跳过这个元素
//            }
//
//            JSONObject jsonObject = (JSONObject) object;
//            for (String key : jsonObject.keySet()) {
//                Field parseField = JSON.toJavaObject(jsonObject.getJSONObject(key), Field.class);
//                parseField = recursiveTraverseField(parseField);
//                map.put(key, parseField);
//            }
//            list.add(map);
//        }
//        field.setValue(list);
//    }
//
//    return field;
//}




    /**
     * 检查 Table table 中是否具有关联表,注意与下面 getAssoAndCollField()  区别
     *
     * @param table Table 对象
     * @return   Map<String , Object>中 key 为关联表名即 associate 或 collection值，
     *            value 是 Field类中的value属性
     */
    public static Map<String, Object> hasAssoAndCollField(Table table){
        Map<String, Field> fieldsMap = table.getFields();
        Set<String> fieldsKeySet = fieldsMap.keySet();
        Map<String, Object> result = new HashMap<>();
        for(String fieldKey : fieldsKeySet){
            Field field = fieldsMap.get(fieldKey);
            if(field.getAssociate() != null && !"".equals(field.getAssociate())){
                result.put(field.getAssociate(), field.getValue());
            }
            else if((field.getCollection() != null && !"".equals(field.getCollection()))){
                result.put(field.getCollection(), field.getValue());
            }
        }
        return result;
    }
}
