<?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="commonCode">

  <!-- ═══════════════════════════════════════════════════════════════ -->
  <!--  CODE_INFO — 1레벨 그룹 마스터                                  -->
  <!-- ═══════════════════════════════════════════════════════════════ -->

  <select id="getCodeInfoList" parameterType="map" resultType="map">
    SELECT
        CODE_INFO
      , CODE_NAME
      , CODE_NAME_ENG
      , DESCRIPTION
      , SORT_ORDER
      , IS_ACTIVE
      , MENU_OBJID
      , COMPANY_CODE
      , CREATED_BY
      , UPDATED_BY
      , CREATED_DATE
      , UPDATED_DATE

    FROM CODE_INFO

    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    <if test="search != null and search != ''">
      AND (
        LOWER(CODE_INFO) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(CODE_NAME) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(COALESCE(CODE_NAME_ENG, '')) LIKE LOWER(CONCAT('%', #{search}, '%'))
      )
    </if>
    <if test="is_active != null">
      AND IS_ACTIVE = #{is_active}
    </if>

    ORDER BY SORT_ORDER ASC, CODE_INFO ASC
    <include refid="common.pagination"/>
  </select>

  <select id="getCodeInfoListCnt" parameterType="map" resultType="int">
    SELECT COUNT(*)

    FROM CODE_INFO

    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    <if test="search != null and search != ''">
      AND (
        LOWER(CODE_INFO) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(CODE_NAME) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(COALESCE(CODE_NAME_ENG, '')) LIKE LOWER(CONCAT('%', #{search}, '%'))
      )
    </if>
    <if test="is_active != null">
      AND IS_ACTIVE = #{is_active}
    </if>
  </select>

  <select id="getCodeInfoInfo" parameterType="map" resultType="map">
    SELECT
        CODE_INFO
      , CODE_NAME
      , CODE_NAME_ENG
      , DESCRIPTION
      , SORT_ORDER
      , IS_ACTIVE
      , MENU_OBJID
      , COMPANY_CODE
      , CREATED_BY
      , UPDATED_BY
      , CREATED_DATE
      , UPDATED_DATE

    FROM CODE_INFO

    WHERE CODE_INFO = #{code_info}
    <include refid="common.companyCodeFilter"/>
  </select>

  <insert id="insertCodeInfo" parameterType="map">
    INSERT INTO CODE_INFO (
        CODE_INFO
      , CODE_NAME
      , CODE_NAME_ENG
      , DESCRIPTION
      , SORT_ORDER
      , IS_ACTIVE
      , MENU_OBJID
      , COMPANY_CODE
      , CREATED_BY
      , UPDATED_BY
      , CREATED_DATE
      , UPDATED_DATE
    ) VALUES (
        #{code_info}
      , #{code_name}
      , #{code_name_eng}
      , #{description}
      , #{sort_order}
      , #{is_active}
      , #{menu_objid}
      , #{company_code}
      , #{created_by}
      , #{updated_by}
      , NOW()
      , NOW()
    )
  </insert>

  <update id="updateCodeInfo" parameterType="map">
    UPDATE CODE_INFO
    <set>
      <if test="code_name != null">CODE_NAME = #{code_name},</if>
      <if test="code_name_eng != null">CODE_NAME_ENG = #{code_name_eng},</if>
      <if test="description != null">DESCRIPTION = #{description},</if>
      <if test="sort_order != null">SORT_ORDER = #{sort_order},</if>
      <if test="is_active != null">IS_ACTIVE = #{is_active},</if>
      <if test="menu_objid != null">MENU_OBJID = #{menu_objid},</if>
      UPDATED_BY = #{updated_by},
      UPDATED_DATE = NOW()
    </set>

    WHERE CODE_INFO = #{code_info}
    <include refid="common.companyCodeFilter"/>
  </update>

  <delete id="deleteCodeInfo" parameterType="map">
    DELETE FROM CODE_INFO

    WHERE CODE_INFO = #{code_info}
    <include refid="common.companyCodeFilter"/>
  </delete>

  <select id="getCodeInfoDuplicateCnt" parameterType="map" resultType="int">
    SELECT COUNT(*)

    FROM CODE_INFO

    WHERE CODE_INFO = #{code_info}
    <include refid="common.companyCodeFilter"/>
  </select>

  <select id="getCodeInfoDuplicateByField" parameterType="map" resultType="int">
    SELECT COUNT(*)

    FROM CODE_INFO

    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    <choose>
      <when test='field == "code_info"'>AND CODE_INFO = #{value}</when>
      <when test='field == "code_name"'>AND CODE_NAME = #{value}</when>
      <when test='field == "code_name_eng"'>AND CODE_NAME_ENG = #{value}</when>
      <otherwise>AND CODE_INFO = #{value}</otherwise>
    </choose>
    <if test="exclude_code != null and exclude_code != ''">
      AND CODE_INFO != #{exclude_code}
    </if>
  </select>

  <!-- ═══════════════════════════════════════════════════════════════ -->
  <!--  CODE_DETAIL — 2레벨 ~ 무한대 트리                              -->
  <!-- ═══════════════════════════════════════════════════════════════ -->

  <select id="getCodeDetailList" parameterType="map" resultType="map">
    SELECT
        CODE_DETAIL_ID
      , CODE_INFO
      , PARENT_DETAIL_ID
      , CODE_VALUE
      , CODE_NAME
      , CODE_NAME_ENG
      , DESCRIPTION
      , DEPTH
      , SORT_ORDER
      , IS_ACTIVE
      , COMPANY_CODE
      , CREATED_BY
      , UPDATED_BY
      , CREATED_DATE
      , UPDATED_DATE

    FROM CODE_DETAIL

    WHERE CODE_INFO = #{code_info}
    <include refid="common.companyCodeFilter"/>
    <choose>
      <when test="parent_detail_id != null">
        AND PARENT_DETAIL_ID = #{parent_detail_id}
      </when>
      <when test="only_roots != null and only_roots == true">
        AND PARENT_DETAIL_ID IS NULL
      </when>
    </choose>
    <if test="search != null and search != ''">
      AND (
        LOWER(CODE_VALUE) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(CODE_NAME) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(COALESCE(CODE_NAME_ENG, '')) LIKE LOWER(CONCAT('%', #{search}, '%'))
      )
    </if>
    <if test="is_active != null">
      AND IS_ACTIVE = #{is_active}
    </if>

    ORDER BY DEPTH ASC, SORT_ORDER ASC, CODE_VALUE ASC
    <include refid="common.pagination"/>
  </select>

  <select id="getCodeDetailListCnt" parameterType="map" resultType="int">
    SELECT COUNT(*)

    FROM CODE_DETAIL

    WHERE CODE_INFO = #{code_info}
    <include refid="common.companyCodeFilter"/>
    <choose>
      <when test="parent_detail_id != null">
        AND PARENT_DETAIL_ID = #{parent_detail_id}
      </when>
      <when test="only_roots != null and only_roots == true">
        AND PARENT_DETAIL_ID IS NULL
      </when>
    </choose>
    <if test="search != null and search != ''">
      AND (
        LOWER(CODE_VALUE) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(CODE_NAME) LIKE LOWER(CONCAT('%', #{search}, '%'))
        OR LOWER(COALESCE(CODE_NAME_ENG, '')) LIKE LOWER(CONCAT('%', #{search}, '%'))
      )
    </if>
    <if test="is_active != null">
      AND IS_ACTIVE = #{is_active}
    </if>
  </select>

  <select id="getCodeDetailInfo" parameterType="map" resultType="map">
    SELECT
        CODE_DETAIL_ID
      , CODE_INFO
      , PARENT_DETAIL_ID
      , CODE_VALUE
      , CODE_NAME
      , CODE_NAME_ENG
      , DESCRIPTION
      , DEPTH
      , SORT_ORDER
      , IS_ACTIVE
      , COMPANY_CODE
      , CREATED_BY
      , UPDATED_BY
      , CREATED_DATE
      , UPDATED_DATE

    FROM CODE_DETAIL

    WHERE CODE_DETAIL_ID = #{code_detail_id}
    <include refid="common.companyCodeFilter"/>
  </select>

  <!--
       그룹 전체 트리 — 재귀 CTE 로 평탄화.
       depth 오름차순 → sort_order 오름차순 → code_value 오름차순.
  -->
  <select id="getCodeDetailTree" parameterType="map" resultType="map">
    WITH RECURSIVE TREE AS (
      SELECT
          CODE_DETAIL_ID
        , CODE_INFO
        , PARENT_DETAIL_ID
        , CODE_VALUE
        , CODE_NAME
        , CODE_NAME_ENG
        , DESCRIPTION
        , DEPTH
        , SORT_ORDER
        , IS_ACTIVE
        , COMPANY_CODE
        , CREATED_BY
        , UPDATED_BY
        , CREATED_DATE
        , UPDATED_DATE
        , ARRAY[SORT_ORDER, CODE_DETAIL_ID] AS PATH

      FROM CODE_DETAIL

      WHERE CODE_INFO = #{code_info}
        AND PARENT_DETAIL_ID IS NULL
        <if test='company_code != null and company_code != "*"'>
          AND (COMPANY_CODE = #{company_code} OR COMPANY_CODE = '*')
        </if>

      UNION ALL

      SELECT
          C.CODE_DETAIL_ID
        , C.CODE_INFO
        , C.PARENT_DETAIL_ID
        , C.CODE_VALUE
        , C.CODE_NAME
        , C.CODE_NAME_ENG
        , C.DESCRIPTION
        , C.DEPTH
        , C.SORT_ORDER
        , C.IS_ACTIVE
        , C.COMPANY_CODE
        , C.CREATED_BY
        , C.UPDATED_BY
        , C.CREATED_DATE
        , C.UPDATED_DATE
        , TREE.PATH || ARRAY[C.SORT_ORDER, C.CODE_DETAIL_ID]

      FROM CODE_DETAIL C
      INNER JOIN TREE ON C.PARENT_DETAIL_ID = TREE.CODE_DETAIL_ID
      WHERE C.CODE_INFO = #{code_info}
        <if test='company_code != null and company_code != "*"'>
          AND (C.COMPANY_CODE = #{company_code} OR C.COMPANY_CODE = '*')
        </if>
    )
    SELECT
        CODE_DETAIL_ID
      , CODE_INFO
      , PARENT_DETAIL_ID
      , CODE_VALUE
      , CODE_NAME
      , CODE_NAME_ENG
      , DESCRIPTION
      , DEPTH
      , SORT_ORDER
      , IS_ACTIVE
      , COMPANY_CODE
      , CREATED_BY
      , UPDATED_BY
      , CREATED_DATE
      , UPDATED_DATE

    FROM TREE

    ORDER BY PATH
  </select>

  <insert id="insertCodeDetail" parameterType="map" useGeneratedKeys="true" keyProperty="code_detail_id" keyColumn="code_detail_id">
    INSERT INTO CODE_DETAIL (
        CODE_INFO
      , PARENT_DETAIL_ID
      , CODE_VALUE
      , CODE_NAME
      , CODE_NAME_ENG
      , DESCRIPTION
      , DEPTH
      , SORT_ORDER
      , IS_ACTIVE
      , COMPANY_CODE
      , CREATED_BY
      , UPDATED_BY
      , CREATED_DATE
      , UPDATED_DATE
    ) VALUES (
        #{code_info}
      , #{parent_detail_id}
      , #{code_value}
      , #{code_name}
      , #{code_name_eng}
      , #{description}
      , #{depth}
      , #{sort_order}
      , #{is_active}
      , #{company_code}
      , #{created_by}
      , #{updated_by}
      , NOW()
      , NOW()
    )
  </insert>

  <update id="updateCodeDetail" parameterType="map">
    UPDATE CODE_DETAIL
    <set>
      <if test="code_value != null">CODE_VALUE = #{code_value},</if>
      <if test="code_name != null">CODE_NAME = #{code_name},</if>
      <if test="code_name_eng != null">CODE_NAME_ENG = #{code_name_eng},</if>
      <if test="description != null">DESCRIPTION = #{description},</if>
      <if test="sort_order != null">SORT_ORDER = #{sort_order},</if>
      <if test="is_active != null">IS_ACTIVE = #{is_active},</if>
      <if test="reparent != null and reparent == true">
        PARENT_DETAIL_ID = #{parent_detail_id},
        DEPTH = #{depth},
      </if>
      UPDATED_BY = #{updated_by},
      UPDATED_DATE = NOW()
    </set>

    WHERE CODE_DETAIL_ID = #{code_detail_id}
    <include refid="common.companyCodeFilter"/>
  </update>

  <delete id="deleteCodeDetail" parameterType="map">
    DELETE FROM CODE_DETAIL

    WHERE CODE_DETAIL_ID = #{code_detail_id}
    <include refid="common.companyCodeFilter"/>
  </delete>

  <select id="getCodeDetailDuplicateCnt" parameterType="map" resultType="int">
    SELECT COUNT(*)

    FROM CODE_DETAIL

    WHERE CODE_INFO = #{code_info}
      AND CODE_VALUE = #{code_value}
    <include refid="common.companyCodeFilter"/>
    <if test="exclude_id != null">
      AND CODE_DETAIL_ID != #{exclude_id}
    </if>
  </select>

  <select id="getCodeDetailChildrenCnt" parameterType="map" resultType="int">
    SELECT COUNT(*)

    FROM CODE_DETAIL

    WHERE PARENT_DETAIL_ID = #{code_detail_id}
    <include refid="common.companyCodeFilter"/>
  </select>

  <select id="getCodeDetailParentDepth" parameterType="map" resultType="int">
    SELECT COALESCE(DEPTH, 1)

    FROM CODE_DETAIL

    WHERE CODE_DETAIL_ID = #{code_detail_id}
    <include refid="common.companyCodeFilter"/>
  </select>

</mapper>
