<?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.zioinfo.esn.auth.mapper.UserAuthMapper">

  <resultMap id="userMap" type="com.zioinfo.esn.auth.EsnUser">
    <id property="id" column="id"/>
    <result property="tenantCode"   column="tenant_code"/>
    <result property="username"     column="username"/>
    <result property="passwordHash" column="password_hash"/>
    <result property="role"         column="role"/>
    <result property="email"        column="email"/>
    <result property="phone"        column="phone"/>
    <result property="active"       column="is_active"/>
    <result property="lastLoginAt"  column="last_login_at"/>
    <result property="createdAt"    column="created_at"/>
    <!-- 로그인 보조 이식 컬럼 (93_esn_login_helper.sql ALTER). -->
    <result property="name"           column="name"/>
    <result property="approvalStatus" column="approval_status"/>
    <!-- UIWS 2FA 이식 컬럼 (91_uiws_port.sql ALTER). -->
    <result property="emailVerifyCode"   column="email_verify_code"/>
    <result property="emailVerifyExpire" column="email_verify_expire"/>
    <result property="loginFailCount"    column="login_fail_count"/>
    <result property="locked"            column="locked"/>
    <result property="otpSecret"         column="otp_secret"/>
    <result property="otpEnabled"        column="otp_enabled"/>
  </resultMap>

  <select id="findByUsername" resultMap="userMap">
    SELECT id, tenant_code, username, password_hash, role, email, phone,
           is_active, last_login_at, created_at, name, approval_status,
           email_verify_code, email_verify_expire, login_fail_count, locked, otp_secret, otp_enabled
    FROM esn_user
    WHERE username = #{username}
  </select>

  <update id="updateLastLogin">
    UPDATE esn_user SET last_login_at = NOW() WHERE username = #{username}
  </update>

  <!-- ── UIWS 2FA 이식: 실패 카운트/잠금/인증코드 갱신 (멱등 UPDATE) ─────────────── -->

  <update id="resetLoginFail">
    UPDATE esn_user SET login_fail_count = 0 WHERE username = #{username}
  </update>

  <update id="incrementLoginFail">
    UPDATE esn_user
    SET login_fail_count = COALESCE(login_fail_count, 0) + 1,
        locked = (COALESCE(login_fail_count, 0) + 1 >= #{maxFail})
    WHERE username = #{username}
  </update>

  <update id="saveEmailCode">
    UPDATE esn_user
    SET email_verify_code = #{code}, email_verify_expire = #{expire}, login_fail_count = 0
    WHERE username = #{username}
  </update>

  <update id="clearEmailCode">
    UPDATE esn_user SET email_verify_code = NULL, email_verify_expire = NULL WHERE username = #{username}
  </update>

  <update id="unlock">
    UPDATE esn_user SET locked = false, login_fail_count = 0 WHERE username = #{username}
  </update>

  <!-- ── 로그인 보조 이식: 회원가입(승인대기)/아이디찾기/비밀번호 초기화 ────────────── -->

  <select id="countByUsername" resultType="int">
    SELECT COUNT(*) FROM esn_user WHERE username = #{username}
  </select>

  <insert id="insertPendingUser">
    INSERT INTO esn_user (tenant_code, username, password_hash, role, name, email, phone,
                          is_active, approval_status, created_at)
    VALUES (#{tenantCode}, #{username}, #{passwordHash}, 'USER', #{name}, #{email}, #{phone},
            FALSE, 'PENDING', NOW())
  </insert>

  <select id="findUsernameByNameEmail" resultType="string">
    SELECT username FROM esn_user
    WHERE name = #{name} AND email = #{email}
    LIMIT 1
  </select>

  <select id="findByUsernameNameEmail" resultMap="userMap">
    SELECT id, tenant_code, username, password_hash, role, email, phone,
           is_active, last_login_at, created_at, name, approval_status,
           email_verify_code, email_verify_expire, login_fail_count, locked, otp_secret, otp_enabled
    FROM esn_user
    WHERE username = #{username} AND name = #{name} AND email = #{email}
  </select>

  <update id="updatePasswordHash">
    UPDATE esn_user SET password_hash = #{passwordHash} WHERE username = #{username}
  </update>

  <!-- ── TOTP(OTP 2차 인증) 이식: 시크릿/등록 확정 갱신 (멱등 UPDATE) ───────────────── -->

  <update id="updateOtpSecret">
    UPDATE esn_user SET otp_secret = #{secret} WHERE username = #{username}
  </update>

  <update id="enableOtp">
    UPDATE esn_user SET otp_enabled = true WHERE username = #{username}
  </update>

  <update id="disableOtp">
    UPDATE esn_user SET otp_secret = NULL, otp_enabled = false WHERE username = #{username}
  </update>

</mapper>
