const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const userModel = require('../models/userModel');
const { getDb } = require('../dbPool');

// 로그인 이력 기록 (서비스 내부 헬퍼 함수)
const recordLoginHistory = async (userId, success, ipAddress, userAgent, failureReason = null) => {
  try {
    const db = await getDb();
    await db.query(
      `INSERT INTO login_logs (user_id, login_time, ip_address, user_agent, login_status, failure_reason) 
       VALUES (?, NOW(), ?, ?, ?, ?)`,
      [userId, ipAddress || 'unknown', userAgent || 'unknown', success ? 'success' : 'failed', failureReason]
    );
  } catch (error) {
    console.error('로그인 이력 기록 실패:', error);
  }
};

const loginService = async (username, password, ipAddress, userAgent) => {
  // 서비스 레이어에서는 더 이상 DB 커넥션을 직접 다루지 않음
  try {
    const user = await userModel.findByUsername(username);

    if (!user) {
      console.log(`[로그인 실패] 사용자를 찾을 수 없음: ${username}`);
      return { success: false, status: 401, error: '아이디 또는 비밀번호가 올바르지 않습니다.' };
    }

    if (user.is_active === false) {
      await recordLoginHistory(user.user_id, false, ipAddress, userAgent, 'account_disabled');
      return { success: false, status: 403, error: '비활성화된 계정입니다. 관리자에게 문의하세요.' };
    }

    if (user.locked_until && new Date(user.locked_until) > new Date()) {
      const remainingTime = Math.ceil((new Date(user.locked_until) - new Date()) / 1000 / 60);
      return { success: false, status: 429, error: `계정이 잠겨있습니다. ${remainingTime}분 후에 다시 시도하세요.` };
    }

    const isValid = await bcrypt.compare(password, user.password);
    if (!isValid) {
      console.log(`[로그인 실패] 비밀번호 불일치: ${username}`);

      // 모델 함수를 사용하여 로그인 실패 처리
      await userModel.incrementFailedLoginAttempts(user.user_id);

      if (user.failed_login_attempts >= 4) {
        await userModel.lockUserAccount(user.user_id);
      }

      await recordLoginHistory(user.user_id, false, ipAddress, userAgent, 'invalid_password');
      return { success: false, status: 401, error: '아이디 또는 비밀번호가 올바르지 않습니다.' };
    }

    // 성공 시 모델 함수를 사용하여 상태 초기화
    await userModel.resetLoginAttempts(user.user_id);


    if (!process.env.JWT_SECRET) {
      throw new Error('JWT_SECRET 환경변수가 설정되지 않았습니다');
    }

    const token = jwt.sign(
      { user_id: user.user_id, username: user.username, role: user.role_name, role_id: user.role_id, access_level: user.access_level, name: user.name || user.username },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN || '24h' }
    );

    const refreshToken = jwt.sign(
      { user_id: user.user_id, type: 'refresh' },
      process.env.JWT_REFRESH_SECRET || process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '7d' }
    );

    await recordLoginHistory(user.user_id, true, ipAddress, userAgent);
    console.log(`[로그인 성공] 사용자: ${user.username} (${user.access_level})`);

    return {
      success: true,
      data: {
        token,
        refreshToken,
        user: {
          user_id: user.user_id,
          username: user.username,
          name: user.name || user.username,
          role: user.role_name,
          access_level: user.access_level
        }
      }
    };
  } catch (error) {
    console.error('Login service error:', error);
    throw new Error('서버 오류가 발생했습니다.');
  }
  // 서비스 레이어에서는 더 이상 DB 커넥션을 직접 다루지 않음
};

module.exports = {
  loginService,
}; 