<?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="go.kr.project.system.loginLog.mapper.LoginLogMapper">

    <!-- 로그인 로그 저장 -->
    <insert id="insertLoginLog" parameterType="LoginLogVO">
        INSERT INTO tb_login_log (
            LOG_ID,
            USER_ID,
            USER_ACNT,
            LOGIN_DTTM,
            IP_ADDR,
            SUCCESS_YN,
            FAIL_REASON,
            LOGIN_TYPE,
            SESSION_ID,
            USER_AGENT,
            DEVICE_INFO,
            REG_DTTM
        ) VALUES (
            CONCAT('LGLG', LPAD(NEXTVAL(seq_login_log_id), 16, '0')),
            #{userId},
            #{userAcnt},
            #{loginDttm},
            #{ipAddr},
            #{successYn},
            #{failReason},
            #{loginType},
            #{sessionId},
            #{userAgent},
            #{deviceInfo},
            NOW()
        )
    </insert>

    <!-- 로그인 로그 조회 -->
    <select id="selectLoginLog" parameterType="String" resultType="LoginLogVO">
        SELECT 
            LOG_ID,
            USER_ID,
            USER_ACNT,
            LOGIN_DTTM,
            IP_ADDR,
            SUCCESS_YN,
            FAIL_REASON,
            LOGIN_TYPE,
            SESSION_ID,
            USER_AGENT,
            DEVICE_INFO,
            REG_DTTM
        FROM 
            tb_login_log
        WHERE 
            LOG_ID = #{logId}
    </select>

    <!-- 조건에 맞는 로그인 로그 목록 조회 -->
    <select id="selectLoginLogList" parameterType="LoginLogSearchVO" resultType="LoginLogVO">
        SELECT 
            LOG_ID,
            USER_ID,
            USER_ACNT,
            LOGIN_DTTM,
            IP_ADDR,
            SUCCESS_YN,
            FAIL_REASON,
            LOGIN_TYPE,
            SESSION_ID,
            USER_AGENT,
            DEVICE_INFO,
            REG_DTTM
        FROM 
            tb_login_log
        <where>
            <if test="searchUserAcnt != null and searchUserAcnt != ''">
                AND USER_ACNT like concat('%',#{searchUserAcnt},'%')
            </if>
            <if test="searchSuccessYn != null and searchSuccessYn != ''">
                AND SUCCESS_YN = #{searchSuccessYn}
            </if>
            <if test="searchStartDt != null and searchStartDt != ''">
                AND LOGIN_DTTM >= STR_TO_DATE(CONCAT(#{searchStartDt},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="searchEndDt != null and searchEndDt != ''">
                AND LOGIN_DTTM &lt;= STR_TO_DATE(CONCAT(#{searchEndDt},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="searchDeviceInfo != null and searchDeviceInfo != ''">
                AND DEVICE_INFO like concat('%',#{searchDeviceInfo},'%')
            </if>
        </where>
        ORDER BY LOGIN_DTTM DESC
        <if test='pagingYn != null and pagingYn == "Y"'>
            LIMIT #{startIndex}, #{perPage}
        </if>
    </select>

    <!-- 조건에 맞는 로그인 로그 개수 조회 -->
    <select id="selectLoginLogCount" parameterType="LoginLogSearchVO" resultType="int">
        SELECT 
            COUNT(*)
        FROM 
            tb_login_log
        <where>
            <if test="searchUserAcnt != null and searchUserAcnt != ''">
                AND USER_ACNT like concat('%',#{searchUserAcnt},'%')
            </if>
            <if test="searchSuccessYn != null and searchSuccessYn != ''">
                AND SUCCESS_YN = #{searchSuccessYn}
            </if>
            <if test="searchStartDt != null and searchStartDt != ''">
                AND LOGIN_DTTM >= STR_TO_DATE(CONCAT(#{searchStartDt},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="searchEndDt != null and searchEndDt != ''">
                AND LOGIN_DTTM &lt;= STR_TO_DATE(CONCAT(#{searchEndDt},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="searchDeviceInfo != null and searchDeviceInfo != ''">
                AND DEVICE_INFO like concat('%',#{searchDeviceInfo},'%')
            </if>
        </where>
    </select>

    <!-- 특정 사용자의 최근 로그인 기록 조회 -->
    <select id="selectRecentLoginLogs" resultType="LoginLogVO">
        SELECT 
            LOG_ID,
            USER_ID,
            USER_ACNT,
            LOGIN_DTTM,
            IP_ADDR,
            SUCCESS_YN,
            FAIL_REASON,
            LOGIN_TYPE,
            SESSION_ID,
            USER_AGENT,
            DEVICE_INFO,
            REG_DTTM
        FROM 
            tb_login_log
        WHERE 
            USER_ACNT = #{userAcnt}
        ORDER BY 
            LOGIN_DTTM DESC
        LIMIT 
            #{limit}
    </select>

    <!-- 특정 기간 내 사용자의 로그인 실패 횟수 조회 -->
    <select id="selectLoginFailureCount" resultType="int">
        SELECT 
            COUNT(*)
        FROM 
            tb_login_log
        WHERE 
            USER_ACNT = #{userAcnt}
            AND SUCCESS_YN = 'N'
            AND LOGIN_DTTM >= #{startDttm}
    </select>

    <!-- 특정 사용자의 다른 디바이스에서의 로그인 기록 조회 -->
    <select id="selectDifferentDeviceLogins" resultType="LoginLogVO">
        SELECT 
            LOG_ID,
            USER_ID,
            USER_ACNT,
            LOGIN_DTTM,
            IP_ADDR,
            SUCCESS_YN,
            FAIL_REASON,
            LOGIN_TYPE,
            SESSION_ID,
            USER_AGENT,
            DEVICE_INFO,
            REG_DTTM
        FROM 
            tb_login_log
        WHERE 
            USER_ACNT = #{userAcnt}
            AND SUCCESS_YN = 'Y'
            AND DEVICE_INFO != #{deviceInfo}
            AND LOGIN_DTTM >= #{startDttm}
        ORDER BY 
            LOGIN_DTTM DESC
    </select>

    <!-- 특정 IP 주소에서의 로그인 시도 횟수 조회 -->
    <select id="selectLoginAttemptsByIp" resultType="int">
        SELECT 
            COUNT(*)
        FROM 
            tb_login_log
        WHERE 
            IP_ADDR = #{ipAddr}
            AND LOGIN_DTTM >= #{startDttm}
    </select>

    <!-- 디바이스 유형별 로그인 통계 조회 -->
    <select id="selectDeviceTypeStats" parameterType="Map" resultType="Map">
        SELECT 
            DEVICE_INFO,
            COUNT(*) as count
        FROM 
            tb_login_log
        <where>
            <if test="searchStartDt != null and searchStartDt != ''">
                AND LOGIN_DTTM >= STR_TO_DATE(CONCAT(#{searchStartDt},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="searchEndDt != null and searchEndDt != ''">
                AND LOGIN_DTTM &lt;= STR_TO_DATE(CONCAT(#{searchEndDt},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="successYn != null and successYn != ''">
                AND SUCCESS_YN = #{successYn}
            </if>
        </where>
        GROUP BY 
            DEVICE_INFO
        ORDER BY 
            count DESC
        LIMIT 10
    </select>

    <!-- 로그인 성공/실패 비율 통계 조회 -->
    <select id="selectSuccessFailStats" parameterType="Map" resultType="Map">
        SELECT 
            SUCCESS_YN,
            COUNT(*) as count
        FROM 
            tb_login_log
        <where>
            <if test="searchStartDt != null and searchStartDt != ''">
                AND LOGIN_DTTM >= STR_TO_DATE(CONCAT(#{searchStartDt},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="searchEndDt != null and searchEndDt != ''">
                AND LOGIN_DTTM &lt;= STR_TO_DATE(CONCAT(#{searchEndDt},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="deviceInfo != null and deviceInfo != ''">
                AND DEVICE_INFO = #{deviceInfo}
            </if>
        </where>
        GROUP BY 
            SUCCESS_YN
    </select>

    <!-- 시간대별 로그인 시도 통계 조회 -->
    <select id="selectHourlyLoginStats" parameterType="Map" resultType="Map">
        SELECT 
            HOUR(LOGIN_DTTM) as hour,
            COUNT(*) as count,
            SUM(CASE WHEN SUCCESS_YN = 'Y' THEN 1 ELSE 0 END) as successCount,
            SUM(CASE WHEN SUCCESS_YN = 'N' THEN 1 ELSE 0 END) as failCount
        FROM 
            tb_login_log
        <where>
            <if test="searchStartDt != null and searchStartDt != ''">
                AND LOGIN_DTTM >= STR_TO_DATE(CONCAT(#{searchStartDt},' 00:00:00'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="searchEndDt != null and searchEndDt != ''">
                AND LOGIN_DTTM &lt;= STR_TO_DATE(CONCAT(#{searchEndDt},' 23:59:59'), '%Y-%m-%d %H:%i:%s')
            </if>
            <if test="deviceInfo != null and deviceInfo != ''">
                AND DEVICE_INFO = #{deviceInfo}
            </if>
        </where>
        GROUP BY 
            HOUR(LOGIN_DTTM)
        ORDER BY 
            hour
    </select>

</mapper>
