package com.ga.common.mybatis;

import com.ga.common.util.EncryptUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

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

/**
 * AES 암호화 컬럼용 TypeHandler.
 *
 * 중요: Spring 빈으로 등록하면 mybatis-spring-boot-starter 가 자동으로
 *      모든 String 컬럼에 적용해 버린다 (BaseTypeHandler<String> 의 generic 때문).
 *      따라서 @Component 를 붙이지 않고, EncryptUtil 만 정적 주입한다.
 *
 * 사용은 컬럼별 명시만 허용:
 *   <result property="residentNo" column="resident_no"
 *           typeHandler="com.ga.common.mybatis.EncryptTypeHandler"/>
 *
 * EncryptUtil 주입은 EncryptTypeHandlerInitializer (별도 @Configuration) 에서 수행.
 */
public class EncryptTypeHandler extends BaseTypeHandler<String> {

    private static EncryptUtil encryptUtil;

    /** 부팅 시 EncryptTypeHandlerInitializer 가 1회 호출 */
    public static void setEncryptUtil(EncryptUtil util) {
        EncryptTypeHandler.encryptUtil = util;
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, encryptUtil != null ? encryptUtil.encrypt(parameter) : parameter);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return decrypt(rs.getString(columnName));
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return decrypt(rs.getString(columnIndex));
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return decrypt(cs.getString(columnIndex));
    }

    private String decrypt(String v) {
        if (v == null || v.isBlank()) return v;
        try {
            return encryptUtil != null ? encryptUtil.decrypt(v) : v;
        } catch (Exception e) {
            // 암호화 안 된 기존 값일 수 있음 → 원본 반환
            return v;
        }
    }
}
