package com.cf.imes.framework.mybatis.core.type;

import com.cf.imes.framework.common.util.json.JsonUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * mb自定义压缩列表类型转换器
 *
 * @author Gqr
 * @since 2024/7/10 10:51
 */
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class CompressObjectListTypeHandler extends BaseTypeHandler<List<?>> {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<?> parameter, JdbcType jdbcType) throws SQLException {
        try {
            String jsonString = objectMapper.writeValueAsString(parameter);
            // 压缩
            String compressJsonString = JsonUtils.zipString(jsonString);
            ps.setString(i, compressJsonString);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error serializing List<Object> to JSON", e);
        }
    }

    @Override
    public List<?> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String jsonStr = rs.getString(columnName);
        return parseJson(jsonStr);
    }

    @Override
    public List<?> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String jsonStr = rs.getString(columnIndex);
        return parseJson(jsonStr);
    }

    @Override
    public List<?> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String jsonStr = cs.getString(columnIndex);
        return parseJson(jsonStr);
    }

    private List<?> parseJson(String jsonStr) {
        if (jsonStr == null || jsonStr.isEmpty()) {
            return null;
        }
        try {
            // Using JavaType to handle List<Object> deserialization
            JavaType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, Object.class);
            // 解压
            String compressJsonString = JsonUtils.unzipString(jsonStr);
            return objectMapper.readValue(compressJsonString, javaType);
        } catch (Exception e) {
            throw new RuntimeException("Error deserializing JSON to List<Object>", e);
        }
    }
}
