<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ga.core.mapper.dict.DataDictionaryMapper">

    <resultMap id="DataDictionaryRespMap" type="com.ga.core.vo.dict.DataDictionaryResp">
        <id property="dictId" column="dict_id"/>
        <result property="tableName"     column="table_name"/>
        <result property="columnName"    column="column_name"/>
        <result property="domainCode"    column="domain_code"/>
        <result property="columnLabel"   column="column_label"/>
        <result property="description"   column="description"/>
        <result property="isPk"          column="is_pk"/>
        <result property="isFk"          column="is_fk"/>
        <result property="fkReference"   column="fk_reference"/>
        <result property="isRequired"    column="is_required"/>
        <result property="defaultValue"  column="default_value"/>
        <result property="businessRule"  column="business_rule"/>
        <result property="sampleValue"   column="sample_value"/>
        <result property="sortOrder"     column="sort_order"/>
        <result property="createdAt"     column="created_at"/>
        <result property="createdBy"     column="created_by"/>
        <result property="updatedAt"     column="updated_at"/>
        <result property="updatedBy"     column="updated_by"/>
        <!-- data_domain join -->
        <result property="domainName"     column="domain_name"/>
        <result property="domainCategory" column="domain_category"/>
        <result property="dataType"       column="data_type"/>
        <result property="length"         column="length"/>
        <result property="maskingType"    column="masking_type"/>
        <result property="encrypted"      column="encrypted"/>
    </resultMap>

    <resultMap id="DataDictionaryFullRespMap" type="com.ga.core.vo.dict.DataDictionaryFullResp">
        <id property="dictId" column="dict_id"/>
        <result property="tableName"       column="table_name"/>
        <result property="columnName"      column="column_name"/>
        <result property="domainCode"      column="domain_code"/>
        <result property="columnLabel"     column="column_label"/>
        <result property="description"     column="description"/>
        <result property="isPk"            column="is_pk"/>
        <result property="isFk"            column="is_fk"/>
        <result property="fkReference"     column="fk_reference"/>
        <result property="isRequired"      column="is_required"/>
        <result property="defaultValue"    column="default_value"/>
        <result property="businessRule"    column="business_rule"/>
        <result property="sampleValue"     column="sample_value"/>
        <result property="sortOrder"       column="sort_order"/>
        <!-- data_domain -->
        <result property="domainName"      column="domain_name"/>
        <result property="domainCategory"  column="domain_category"/>
        <result property="maskingType"     column="masking_type"/>
        <result property="encrypted"       column="encrypted"/>
        <!-- information_schema -->
        <result property="physicalDataType"  column="physical_data_type"/>
        <result property="physicalLength"    column="physical_length"/>
        <result property="physicalPrecision" column="physical_precision"/>
        <result property="physicalScale"     column="physical_scale"/>
        <result property="physicalNullable"  column="physical_nullable"/>
        <result property="physicalDefault"   column="physical_default"/>
        <result property="physicalComment"   column="physical_comment"/>
        <result property="ordinalPosition"   column="ordinal_position"/>
    </resultMap>

    <sql id="dictDomainJoinCols">
        d.dict_id, d.table_name, d.column_name, d.domain_code,
        d.column_label, d.description, d.is_pk, d.is_fk, d.fk_reference,
        d.is_required, d.default_value, d.business_rule, d.sample_value, d.sort_order,
        d.created_at, d.created_by, d.updated_at, d.updated_by,
        dom.domain_name, dom.domain_category, dom.data_type,
        dom.length, dom.masking_type, dom.encrypted
    </sql>

    <select id="selectList" resultMap="DataDictionaryRespMap">
        SELECT <include refid="dictDomainJoinCols"/>
        FROM data_dictionary d
        LEFT JOIN data_domain dom ON dom.domain_code = d.domain_code
        <where>
            <if test="tableName != null and tableName != ''">
                AND d.table_name = #{tableName}
            </if>
            <if test="domainCode != null and domainCode != ''">
                AND d.domain_code = #{domainCode}
            </if>
            <if test="searchKeyword != null and searchKeyword != ''">
                AND (d.column_name LIKE CONCAT('%', #{searchKeyword}, '%')
                  OR d.column_label LIKE CONCAT('%', #{searchKeyword}, '%'))
            </if>
        </where>
        ORDER BY d.table_name, d.sort_order, d.column_name
    </select>

    <!-- 특정 테이블의 모든 컬럼 (도메인 미등록 컬럼도 노출) -->
    <select id="selectByTable" resultMap="DataDictionaryRespMap">
        SELECT <include refid="dictDomainJoinCols"/>
        FROM data_dictionary d
        LEFT JOIN data_domain dom ON dom.domain_code = d.domain_code
        WHERE d.table_name = #{tableName}
        ORDER BY d.sort_order, d.column_name
    </select>

    <!-- v_data_dictionary_full VIEW 조회. View 에는 sort_order 가 없음 -->
    <select id="selectFromView" resultMap="DataDictionaryFullRespMap">
        SELECT *
        FROM v_data_dictionary_full
        <where>
            <if test="tableName != null and tableName != ''">
                AND table_name = #{tableName}
            </if>
        </where>
        ORDER BY table_name, ordinal_position
    </select>

    <select id="selectTables" resultType="string">
        SELECT DISTINCT table_name
        FROM data_dictionary
        ORDER BY table_name
    </select>

    <select id="selectById" resultMap="DataDictionaryRespMap">
        SELECT <include refid="dictDomainJoinCols"/>
        FROM data_dictionary d
        LEFT JOIN data_domain dom ON dom.domain_code = d.domain_code
        WHERE d.dict_id = #{dictId}
    </select>

    <insert id="insert" parameterType="com.ga.core.vo.dict.DataDictionaryVO" useGeneratedKeys="true" keyProperty="dictId">
        INSERT INTO data_dictionary (
            table_name, column_name, domain_code, column_label, description,
            is_pk, is_fk, fk_reference, is_required, default_value,
            business_rule, sample_value, sort_order, created_at, created_by
        ) VALUES (
            #{tableName}, #{columnName}, #{domainCode}, #{columnLabel}, #{description},
            #{isPk}, #{isFk}, #{fkReference}, #{isRequired}, #{defaultValue},
            #{businessRule}, #{sampleValue}, #{sortOrder}, NOW(), #{createdBy}
        )
    </insert>

    <update id="update" parameterType="com.ga.core.vo.dict.DataDictionaryVO">
        UPDATE data_dictionary SET
            table_name    = #{tableName},
            column_name   = #{columnName},
            domain_code   = #{domainCode},
            column_label  = #{columnLabel},
            description   = #{description},
            is_pk         = #{isPk},
            is_fk         = #{isFk},
            fk_reference  = #{fkReference},
            is_required   = #{isRequired},
            default_value = #{defaultValue},
            business_rule = #{businessRule},
            sample_value  = #{sampleValue},
            sort_order    = #{sortOrder},
            updated_at    = NOW(),
            updated_by    = #{updatedBy}
        WHERE dict_id = #{dictId}
    </update>

    <delete id="delete">
        DELETE FROM data_dictionary WHERE dict_id = #{dictId}
    </delete>

    <select id="countDomainByCode" resultType="int">
        SELECT COUNT(*) FROM data_domain WHERE domain_code = #{domainCode}
    </select>

</mapper>
