package cn.axzo.workflow.common.enums;

import cn.axzo.workflow.common.model.dto.AmountFieldDTO;
import cn.axzo.workflow.common.model.dto.ContactsPersonDTO;
import cn.axzo.workflow.common.model.dto.UploadFieldDTO;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 流程引擎表单字段类型枚举
 * <p>
 * 参考文档：{@see https://alidocs.dingtalk.com/i/nodes/ZgpG2NdyVXKy17o6fQ5nKGvMWMwvDqPk}
 *
 * @author wangli
 * @since 2025-08-04 11:44
 */
public enum FormFieldTypeEnum {
    input("input", "文本", new TypeReference<String>() {
    }),
    textarea("textarea", "多行文本", new TypeReference<String>() {
    }),
    upload("upload", "上传文件", new TypeReference<List<UploadFieldDTO>>() {
    }),
    image("image", "图片", new TypeReference<List<UploadFieldDTO>>() {
    }),
    date("date", "日期", new TypeReference<String>() {
    }),
    customComponent("customComponent", "自定义组件", new TypeReference<List<Map<String, Object>>>() {
    }),
    taskOrder("taskOrder", "任务顺序", new TypeReference<Map<String, Object>>() {
    }),
    rectifyOrder("rectifyOrder", "整改顺序", new TypeReference<Map<String, Object>>() {
    }),
    changeSignatureOrder("changeSignatureOrder", "变更签署顺序", new TypeReference<Map<String, Object>>() {
    }),
    contacts("contacts", "联系人", new TypeReference<List<ContactsPersonDTO>>() {
    }),
    amount("amount", "金额", new TypeReference<AmountFieldDTO>() {
    }),
    decimal("decimal", "小数", new TypeReference<Map<String, Object>>() {
    }),
    ;

    private final String type;
    private final String desc;
    private final TypeReference<?> typeReference;

    FormFieldTypeEnum(String type, String desc, TypeReference<?> typeReference) {
        this.type = type;
        this.desc = desc;
        this.typeReference = typeReference;
    }

    public String getType() {
        return type;
    }

    public String getDesc() {
        return desc;
    }

    public TypeReference<?> getTypeReference() {
        return typeReference;
    }

    public static FormFieldTypeEnum valueOfType(String type) {
        return Arrays.stream(FormFieldTypeEnum.values())
                .filter(i -> Objects.equals(i.getType(), type))
                .findAny()
                .orElse(null);
    }

    public static Object parseValue(String type, Object fieldValue, Map<String, Object> fieldParams) {
        FormFieldTypeEnum fieldType = valueOfType(type);
        if (fieldType == null) {
            return null;
        }
        TypeReference<?> typeReference = fieldType.getTypeReference();
        if (typeReference == null || typeReference.getType() == null) {
            return fieldValue;
        }
        if (fieldValue == null) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // 如果已经是目标类型，直接返回
            if (objectMapper.constructType(typeReference.getType()).getRawClass().isInstance(fieldValue)) {
                return fieldValue;
            }
            // 先转为字符串再反序列化
            String json = fieldValue.toString();
            if (!(fieldValue instanceof String)) {
                json = objectMapper.writeValueAsString(fieldValue);
            }
            Object defaultValue = handleDefault(fieldParams, json, fieldType);
            if (Objects.nonNull(defaultValue)) {
                return fieldValue;
            }
            if (Objects.equals(type, "decimal")) {
                // 特殊处理 decimal 类型，确保返回的 Map 包含 unit 字段
                Map<String, Object> decimalMap = new HashMap<>();
                decimalMap.put("value", fieldValue);
                decimalMap.put("unit", fieldParams.getOrDefault("unit", ""));
                return decimalMap;
            }
            return objectMapper.readValue(json, typeReference);
        } catch (Exception e) {
            throw new RuntimeException("字段值解析失败: " + fieldValue, e);
        }
    }

    private static Object handleDefault(Map<String, Object> fieldParams, String json, FormFieldTypeEnum fieldType) {
        if (Objects.equals("[]", json)) {
            switch (fieldType) {
                case upload:
                case image:
                case customComponent:
                case taskOrder:
                case rectifyOrder:
                case changeSignatureOrder:
                case contacts:
                    // 对于这些类型，返回空列表而不是空字符串
                    return Collections.emptyList();
                case decimal:
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("value", 0);
                    map.put("unit", fieldParams.getOrDefault("unit", ""));
                    return map;
                default:
                    return "";
            }
        }
        return null;
    }
}
