package com.ycwl.basic.puzzle.util;

import cn.hutool.core.util.StrUtil;
import com.ycwl.basic.puzzle.dto.ElementCreateRequest;
import com.ycwl.basic.puzzle.element.enums.ElementType;
import com.ycwl.basic.puzzle.entity.PuzzleElementEntity;
import com.ycwl.basic.utils.JacksonUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * Element配置辅助类
 * 处理ElementCreateRequest到PuzzleElementEntity的转换
 * 负责config和configMap之间的序列化/反序列化
 *
 * @author Claude
 * @since 2025-01-18
 */
@Slf4j
public class ElementConfigHelper {

    /**
     * 将ElementCreateRequest转换为PuzzleElementEntity
     *
     * @param request 创建请求
     * @return Entity对象
     */
    public static PuzzleElementEntity toEntity(ElementCreateRequest request) {
        PuzzleElementEntity entity = new PuzzleElementEntity();

        // 基本属性
        entity.setTemplateId(request.getTemplateId());
        entity.setElementType(request.getElementType());
        entity.setElementKey(request.getElementKey());
        entity.setElementName(request.getElementName());

        // 位置和布局属性
        entity.setXPosition(request.getXPosition());
        entity.setYPosition(request.getYPosition());
        entity.setWidth(request.getWidth());
        entity.setHeight(request.getHeight());
        entity.setZIndex(request.getZIndex());
        entity.setRotation(request.getRotation());
        entity.setOpacity(request.getOpacity());

        // 处理配置：优先使用config字符串，否则将configMap序列化为JSON
        String configJson = getConfigJson(request);
        entity.setConfig(configJson);

        return entity;
    }

    /**
     * 从Request获取JSON配置字符串
     * 优先级：config字符串 > configMap序列化
     *
     * @param request 创建请求
     * @return JSON配置字符串
     */
    public static String getConfigJson(ElementCreateRequest request) {
        // 优先使用config字段
        if (StrUtil.isNotBlank(request.getConfig())) {
            return request.getConfig();
        }

        // 否则将configMap序列化为JSON
        if (request.getConfigMap() != null && !request.getConfigMap().isEmpty()) {
            try {
                return JacksonUtil.toJson(request.getConfigMap());
            } catch (Exception e) {
                log.error("configMap序列化为JSON失败", e);
                throw new IllegalArgumentException("配置序列化失败: " + e.getMessage());
            }
        }

        // 都为空则返回空JSON对象
        return "{}";
    }

    /**
     * 将JSON配置字符串解析为Map
     *
     * @param configJson JSON配置字符串
     * @return Map对象
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> parseConfigToMap(String configJson) {
        if (StrUtil.isBlank(configJson)) {
            return Map.of();
        }

        try {
            return JacksonUtil.fromJson(configJson, Map.class);
        } catch (Exception e) {
            log.error("JSON解析为Map失败: {}", configJson, e);
            return Map.of();
        }
    }

    /**
     * 验证元素类型是否有效
     *
     * @param elementType 元素类型
     * @return true-有效，false-无效
     */
    public static boolean isValidElementType(String elementType) {
        if (StrUtil.isBlank(elementType)) {
            return false;
        }

        try {
            ElementType type = ElementType.fromCode(elementType);
            return type.isImplemented();
        } catch (IllegalArgumentException ex) {
            return false;
        }
    }

    /**
     * 验证元素配置是否完整
     *
     * @param request 创建请求
     * @throws IllegalArgumentException 配置不完整时抛出
     */
    public static void validateRequest(ElementCreateRequest request) {
        if (request.getTemplateId() == null) {
            throw new IllegalArgumentException("模板ID不能为空");
        }

        if (StrUtil.isBlank(request.getElementType())) {
            throw new IllegalArgumentException("元素类型不能为空");
        }

        if (!isValidElementType(request.getElementType())) {
            throw new IllegalArgumentException("不支持的元素类型: " + request.getElementType());
        }

        if (StrUtil.isBlank(request.getElementKey())) {
            throw new IllegalArgumentException("元素标识不能为空");
        }

        // 验证位置属性
        if (request.getXPosition() == null || request.getYPosition() == null) {
            throw new IllegalArgumentException("位置坐标不能为空");
        }

        if (request.getWidth() == null || request.getHeight() == null) {
            throw new IllegalArgumentException("宽高不能为空");
        }

        if (request.getWidth() <= 0 || request.getHeight() <= 0) {
            throw new IllegalArgumentException("宽高必须大于0");
        }

        // 验证配置
        if (StrUtil.isBlank(request.getConfig()) &&
                (request.getConfigMap() == null || request.getConfigMap().isEmpty())) {
            throw new IllegalArgumentException("元素配置不能为空（config或configMap至少提供一个）");
        }
    }
}
