package com.zioinfo.esn.auth.mapper;

import com.zioinfo.esn.auth.EsnUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;

@Mapper
public interface UserAuthMapper {
    EsnUser findByUsername(@Param("username") String username);
    int updateLastLogin(@Param("username") String username);

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

    /** 로그인 성공 시 실패 카운트 초기화. */
    int resetLoginFail(@Param("username") String username);

    /** 로그인 실패 누적(+1) 및 임계 도달 시 잠금. */
    int incrementLoginFail(@Param("username") String username, @Param("maxFail") int maxFail);

    /** 1차 통과 시 이메일 인증코드/만료 저장(verify 단계에서 검증). */
    int saveEmailCode(@Param("username") String username,
                      @Param("code") String code,
                      @Param("expire") LocalDateTime expire);

    /** 2차 검증 성공 시 코드 폐기. */
    int clearEmailCode(@Param("username") String username);

    /** 관리자 잠금 해제(실패 카운트/잠금 초기화). */
    int unlock(@Param("username") String username);

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

    /** 보류 시크릿 저장(등록 확정 전). otp_enabled 은 건드리지 않는다(verify/confirm 에서 확정). */
    int updateOtpSecret(@Param("username") String username, @Param("secret") String secret);

    /** 등록 확정: otp_enabled=true (시크릿은 유지). */
    int enableOtp(@Param("username") String username);

    /** 해제/초기화: 시크릿 폐기 + otp_enabled=false. (마이페이지 해제) */
    int disableOtp(@Param("username") String username);

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

    /** 아이디 중복 확인. */
    int countByUsername(@Param("username") String username);

    /** 회원가입 — 승인대기(is_active=FALSE, approval_status='PENDING') INSERT. */
    int insertPendingUser(@Param("tenantCode") String tenantCode,
                          @Param("username") String username,
                          @Param("passwordHash") String passwordHash,
                          @Param("name") String name,
                          @Param("email") String email,
                          @Param("phone") String phone);

    /** 아이디 찾기 — 이름+이메일 일치 username 1건(없으면 null). */
    String findUsernameByNameEmail(@Param("name") String name, @Param("email") String email);

    /** 비밀번호 초기화 — 아이디+이름+이메일 모두 일치하는 사용자(없으면 null). */
    EsnUser findByUsernameNameEmail(@Param("username") String username,
                                    @Param("name") String name,
                                    @Param("email") String email);

    /** 임시 비밀번호(BCrypt) 갱신. */
    int updatePasswordHash(@Param("username") String username,
                           @Param("passwordHash") String passwordHash);
}
