package com.zioinfo.mall.auth.mapper;

import com.zioinfo.mall.auth.MallUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;

import java.time.LocalDateTime;

/**
 * 계정 매퍼. findByUsername/insert/countByUsername 는 UserMapper.xml 에 정의(2FA 컬럼 포함 resultMap).
 * UIWS 2FA 이식 UPDATE 5종은 어노테이션으로 추가 — XML 중복 정의 없음(빈 등록 충돌 회피).
 */
@Mapper
public interface UserMapper {

    MallUser findByUsername(@Param("username") String username);

    int insert(MallUser user);

    int countByUsername(@Param("username") String username);

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

    /** 로그인 성공 시 실패 카운트 초기화. */
    @Update("UPDATE mall_account SET login_fail_count = 0 WHERE username = #{username}")
    int resetLoginFail(@Param("username") String username);

    /** 로그인 실패 누적(+1) 및 임계 도달 시 잠금. */
    @Update("""
            UPDATE mall_account
            SET login_fail_count = COALESCE(login_fail_count, 0) + 1,
                locked = (COALESCE(login_fail_count, 0) + 1 >= #{maxFail})
            WHERE username = #{username}
            """)
    int incrementLoginFail(@Param("username") String username, @Param("maxFail") int maxFail);

    /** 1차 통과 시 이메일 인증코드/만료 저장(verify 단계에서 검증). */
    @Update("""
            UPDATE mall_account
            SET email_verify_code = #{code}, email_verify_expire = #{expire}, login_fail_count = 0
            WHERE username = #{username}
            """)
    int saveEmailCode(@Param("username") String username,
                      @Param("code") String code,
                      @Param("expire") LocalDateTime expire);

    /** 2차 검증 성공 시 코드 폐기. */
    @Update("UPDATE mall_account SET email_verify_code = NULL, email_verify_expire = NULL WHERE username = #{username}")
    int clearEmailCode(@Param("username") String username);

    /** 관리자 잠금 해제(실패 카운트/잠금 초기화). */
    @Update("UPDATE mall_account SET locked = false, login_fail_count = 0 WHERE username = #{username}")
    int unlock(@Param("username") String username);
}
