package vip.xiaonuo.coldchain.core.handler.abs;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.io.IOException;

public abstract class GenericTypeHandler<T> extends BaseTypeHandler<T> {

    public GenericTypeHandler() {
    }

    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 将对象转换为 JSON 字符串存入数据库
    @Override
    public void setNonNullParameter(java.sql.PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws java.sql.SQLException {
        try {
            String json = objectMapper.writeValueAsString(parameter);
            ps.setString(i, json);
        } catch (JsonProcessingException e) {
            throw new java.sql.SQLException("Error serializing object to JSON", e);
        }
    }

    // 从数据库中读取 JSON 字符串，并转换为对象
    @Override
    public T getNullableResult(java.sql.ResultSet rs, String columnName) throws java.sql.SQLException {
        try {
            String json = rs.getString(columnName);
            if (json != null) {
                return objectMapper.readValue(json, specificType());
            }
            return null;
        } catch (IOException e) {
            throw new java.sql.SQLException("Error deserializing JSON to object", e);
        }
    }

    @Override
    public T getNullableResult(java.sql.ResultSet rs, int columnIndex) throws java.sql.SQLException {
        try {
            String json = rs.getString(columnIndex);
            if (json != null) {
                return objectMapper.readValue(json, specificType());
            }
            return null;
        } catch (IOException e) {
            throw new java.sql.SQLException("Error deserializing JSON to object", e);
        }
    }

    @Override
    public T getNullableResult(java.sql.CallableStatement cs, int columnIndex) throws java.sql.SQLException {
        try {
            String json = cs.getString(columnIndex);
            if (json != null) {
                return objectMapper.readValue(json, specificType());
            }
            return null;
        } catch (IOException e) {
            throw new java.sql.SQLException("Error deserializing JSON to object", e);
        }
    }

    protected abstract TypeReference<T> specificType();

}
