package kr.iotdoor.boot.mapper;

import kr.iotdoor.boot.model.user.UserAccount;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

@Mapper
public interface UserMapper {

    @Select("""
        SELECT
            USER_IDNTF_NO,
            USER_ID,
            PSWD,
            USER_NM,
            EML_ADDR,
            USER_STTS_CD,
            USER_TYPE_CD,
            JOIN_DT,
            INDVDL_INFO_AGRE_DT,
            LOCK_YN,
            LGN_FAIL_NMTM,
            LOCK_DT,
            LAST_LGN_DT
        FROM TN_USER
        WHERE USER_ID = #{userId}
        """)
    UserAccount selectByUserId(@Param("userId") String userId);

    @Select("""
        SELECT COUNT(*)
        FROM TN_USER
        WHERE USER_ID = #{userId}
        """)
    int countByUserId(@Param("userId") String userId);

    @Select("""
        <script>
        SELECT
            USER_IDNTF_NO,
            USER_ID,
            PSWD,
            USER_NM,
            EML_ADDR,
            USER_STTS_CD,
            USER_TYPE_CD,
            JOIN_DT,
            INDVDL_INFO_AGRE_DT,
            LOCK_YN,
            LGN_FAIL_NMTM,
            LOCK_DT,
            LAST_LGN_DT
        FROM TN_USER
        <where>
            <if test="keyword != null and keyword != ''">
                (
                    USER_ID LIKE CONCAT('%', #{keyword}, '%')
                    OR USER_NM LIKE CONCAT('%', #{keyword}, '%')
                    OR EML_ADDR LIKE CONCAT('%', #{keyword}, '%')
                )
            </if>
        </where>
        ORDER BY JOIN_DT DESC, USER_ID ASC
        </script>
        """)
    List<UserAccount> selectUserList(@Param("keyword") String keyword);

    @Select("""
        SELECT
            USER_IDNTF_NO,
            USER_ID,
            PSWD,
            USER_NM,
            EML_ADDR,
            USER_STTS_CD,
            USER_TYPE_CD,
            JOIN_DT,
            INDVDL_INFO_AGRE_DT,
            LOCK_YN,
            LGN_FAIL_NMTM,
            LOCK_DT,
            LAST_LGN_DT
        FROM TN_USER
        WHERE USER_IDNTF_NO = #{userIdntfNo}
        """)
    UserAccount selectByUserIdntfNo(@Param("userIdntfNo") String userIdntfNo);

    @Select("""
        SELECT COUNT(*)
        FROM TN_USER
        WHERE USER_STTS_CD IN ('A', 'P')
        """)
    int countActiveUsers();

    @Select("""
        SELECT COUNT(*)
        FROM TN_USER
        WHERE USER_TYPE_CD = 'ADM'
          AND USER_STTS_CD IN ('A', 'P')
        """)
    int countAdminUsers();

    @Insert("""
        INSERT INTO TN_USER (
            USER_IDNTF_NO,
            USER_ID,
            PSWD,
            USER_NM,
            EML_ADDR,
            USER_STTS_CD,
            USER_TYPE_CD,
            JOIN_DT,
            INDVDL_INFO_AGRE_DT,
            LOCK_YN,
            LGN_FAIL_NMTM,
            LOCK_DT,
            LAST_LGN_DT
        ) VALUES (
            #{userIdntfNo},
            #{userId},
            #{pswd},
            #{userNm},
            #{emlAddr},
            #{userSttsCd},
            #{userTypeCd},
            #{joinDt},
            #{indvdlInfoAgreDt},
            #{lockYn},
            #{lgnFailNmtm},
            #{lockDt},
            #{lastLgnDt}
        )
        """)
    int insertUser(UserAccount userAccount);

    @Update("""
        UPDATE TN_USER
        SET LAST_LGN_DT = CURRENT_TIMESTAMP
        WHERE USER_IDNTF_NO = #{userIdntfNo}
        """)
    int updateLastLoginDt(@Param("userIdntfNo") String userIdntfNo);

    @Update("""
        <script>
        UPDATE TN_USER
        SET
            USER_NM = #{userNm},
            EML_ADDR = #{emlAddr},
            USER_STTS_CD = #{userSttsCd},
            USER_TYPE_CD = #{userTypeCd},
            INDVDL_INFO_AGRE_DT = COALESCE(INDVDL_INFO_AGRE_DT, CURRENT_TIMESTAMP),
            LOCK_YN = 'N',
            LGN_FAIL_NMTM = 0,
            LOCK_DT = NULL
            <if test="pswd != null and pswd != ''">
                , PSWD = #{pswd}
            </if>
        WHERE USER_IDNTF_NO = #{userIdntfNo}
        </script>
        """)
    int updateUser(UserAccount userAccount);
}
