<?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.settle.PaymentBatchMapper">

    <!-- VO ResultMap: INSERT/UPDATE 전용, 조인 없음 -->
    <resultMap id="VOMap" type="com.ga.core.vo.settle.PaymentBatchVO"/>

    <!--
        목록 조회용 ResultMap: 상태명 포함, items 없음.
        목록에서 items 를 채울 필요가 없으므로 collection 미포함.
    -->
    <resultMap id="RespListMap" type="com.ga.core.vo.settle.PaymentBatchResp">
        <id     property="batchId"         column="batch_id"/>
        <result property="settleMonth"     column="settle_month"/>
        <result property="batchName"       column="batch_name"/>
        <result property="status"          column="status"/>
        <result property="statusName"      column="status_name"/>
        <result property="totalCount"      column="total_count"/>
        <result property="totalPayable"    column="total_payable"/>
        <result property="createdAt"       column="created_at"/>
        <result property="createdBy"       column="created_by"/>
        <result property="finalizedAt"     column="finalized_at"/>
        <result property="finalizedBy"     column="finalized_by"/>
        <result property="finalizedByName" column="finalized_by_name"/>
        <result property="updatedAt"       column="updated_at"/>
    </resultMap>

    <!--
        상세 조회용 ResultMap: RespListMap 의 모든 컬럼 +
        items collection (PaymentBatchItemMapper.selectByBatchId 호출).
        select N+1 방지를 위해 별도 mapper select 참조.
    -->
    <resultMap id="RespDetailMap" type="com.ga.core.vo.settle.PaymentBatchResp"
               extends="RespListMap">
        <collection property="items"
                    ofType="com.ga.core.vo.settle.PaymentBatchItemResp"
                    select="com.ga.core.mapper.settle.PaymentBatchItemMapper.selectByBatchId"
                    column="batch_id"/>
    </resultMap>

    <!-- 목록 SELECT 공통 컬럼 -->
    <sql id="batchCols">
        b.batch_id,
        b.settle_month,
        b.batch_name,
        b.status,
        (SELECT cc.code_name FROM common_code cc
            WHERE cc.group_code = 'PAYMENT_BATCH_STATUS' AND cc.code = b.status) AS status_name,
        b.total_count,
        b.total_payable,
        b.created_at,
        b.created_by,
        b.finalized_at,
        b.finalized_by,
        u.user_name AS finalized_by_name,
        b.updated_at
    </sql>

    <!-- JOIN 절: finalized_by → users -->
    <sql id="batchJoins">
        FROM payment_batch b
        LEFT JOIN users u ON u.user_id = b.finalized_by
    </sql>

    <!--
        배치 생성 INSERT.
        useGeneratedKeys=true 로 채번된 batch_id 를 vo.batchId 에 주입.
        status 기본값 DRAFT, total_count/total_payable 기본 0.
    -->
    <insert id="insert" parameterType="com.ga.core.vo.settle.PaymentBatchVO"
            useGeneratedKeys="true" keyProperty="batchId">
        INSERT INTO payment_batch
            (settle_month, batch_name, status, total_count, total_payable,
             created_at, created_by)
        VALUES
            (#{settleMonth}, #{batchName}, 'DRAFT', 0, 0,
             NOW(), #{createdBy})
    </insert>

    <!--
        배치 목록 조회 — PageHelper startPage() 호환.
        settleMonth / status (SearchParam 상속) 필터.
        최신 순(batch_id DESC) 정렬.
    -->
    <select id="selectList" resultMap="RespListMap">
        SELECT <include refid="batchCols"/>
        <include refid="batchJoins"/>
        <where>
            <if test="settleMonth != null and settleMonth != ''">
                AND b.settle_month = #{settleMonth}
            </if>
            <if test="status != null and status != ''">
                AND b.status = #{status}
            </if>
        </where>
        ORDER BY b.batch_id DESC
    </select>

    <!--
        배치 단건 상세 조회.
        RespDetailMap 의 collection 이 selectByBatchId 를 자동 호출해
        items 목록을 채운다.
    -->
    <select id="selectById" resultMap="RespDetailMap">
        SELECT <include refid="batchCols"/>
        <include refid="batchJoins"/>
        WHERE b.batch_id = #{batchId}
    </select>

    <!--
        포함 건수 / 합계 재집계.
        updateItem 호출 직후 반드시 실행.
        total_count  : included=true 인 항목 수
        total_payable: included=true 인 항목의 payable_amount 합계 (없으면 0)
    -->
    <update id="recalcTotals">
        UPDATE payment_batch
           SET total_count   = (
                   SELECT COUNT(*)
                     FROM payment_batch_item
                    WHERE batch_id = #{batchId}
                      AND included = true
               ),
               total_payable = (
                   SELECT COALESCE(SUM(payable_amount), 0)
                     FROM payment_batch_item
                    WHERE batch_id = #{batchId}
                      AND included = true
               ),
               updated_at = NOW()
         WHERE batch_id = #{batchId}
    </update>

    <!--
        배치 상태 변경.
        FINALIZED 시에만 finalized_at / finalized_by 기록.
        CANCELLED 등 다른 상태 전이 시에는 NULL 로 두지 않고 기존 값 유지.
    -->
    <update id="updateStatus">
        UPDATE payment_batch
           SET status       = #{status},
               finalized_at = CASE WHEN #{status} = 'FINALIZED' THEN NOW()        ELSE finalized_at END,
               finalized_by = CASE WHEN #{status} = 'FINALIZED' THEN #{userId}    ELSE finalized_by END,
               updated_at   = NOW()
         WHERE batch_id = #{batchId}
    </update>

    <!-- 페이징 count 쿼리 -->
    <select id="countByCondition" resultType="int">
        SELECT COUNT(*)
          FROM payment_batch b
        <where>
            <if test="settleMonth != null and settleMonth != ''">
                AND b.settle_month = #{settleMonth}
            </if>
            <if test="status != null and status != ''">
                AND b.status = #{status}
            </if>
        </where>
    </select>

</mapper>
