const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

/**
 * Tạo JWT token
 * @param {Object} payload - Dữ liệu để encode vào token
 * @param {string} expiresIn - Thời gian hết hạn (default: '24h')
 * @returns {string} JWT token
 */
const generateToken = (payload, expiresIn = '24h') => {
  return jwt.sign(payload, process.env.JWT_SECRET || 'your-secret-key', { expiresIn });
};

/**
 * Verify JWT token
 * @param {string} token - JWT token
 * @returns {Object} Decoded payload
 */
const verifyToken = (token) => {
  return jwt.verify(token, process.env.JWT_SECRET || 'your-secret-key');
};

/**
 * Hash password
 * @param {string} password - Plain text password
 * @param {number} saltRounds - Số vòng salt (default: 10)
 * @returns {Promise<string>} Hashed password
 */
const hashPassword = async (password, saltRounds = 10) => {
  return await bcrypt.hash(password, saltRounds);
};

/**
 * Compare password with hash
 * @param {string} password - Plain text password
 * @param {string} hash - Hashed password
 * @returns {Promise<boolean>} True if match, false otherwise
 */
const comparePassword = async (password, hash) => {
  return await bcrypt.compare(password, hash);
};

/**
 * Tạo payload cho JWT token từ user data
 * @param {Object} user - User object
 * @returns {Object} JWT payload
 */
const createTokenPayload = (user) => {
  return {
    user_id: user.user_id,
    username: user.username,
    email: user.email,
    role_id: user.role_id,
    role_name: user.role_name
  };
};

/**
 * Extract token from Authorization header
 * @param {string} authHeader - Authorization header value
 * @returns {string|null} Token or null
 */
const extractTokenFromHeader = (authHeader) => {
  if (!authHeader) return null;
  
  const parts = authHeader.split(' ');
  if (parts.length !== 2 || parts[0] !== 'Bearer') {
    return null;
  }
  
  return parts[1];
};

/**
 * Tạo refresh token
 * @param {Object} payload - Payload data
 * @returns {string} Refresh token
 */
const generateRefreshToken = (payload) => {
  return jwt.sign(
    { ...payload, type: 'refresh' }, 
    process.env.JWT_REFRESH_SECRET || 'your-refresh-secret-key', 
    { expiresIn: '7d' }
  );
};

/**
 * Verify refresh token
 * @param {string} token - Refresh token
 * @returns {Object} Decoded payload
 */
const verifyRefreshToken = (token) => {
  return jwt.verify(token, process.env.JWT_REFRESH_SECRET || 'your-refresh-secret-key');
};

/**
 * Tạo response data cho login
 * @param {Object} user - User object
 * @param {string} accessToken - Access token
 * @param {string} refreshToken - Refresh token
 * @returns {Object} Login response data
 */
const createLoginResponse = (user, accessToken, refreshToken = null) => {
  const response = {
    user: {
      user_id: user.user_id,
      username: user.username,
      email: user.email,
      full_name: user.full_name,
      phone: user.phone,
      role_id: user.role_id,
      role_name: user.role_name,
      is_active: user.is_active
    },
    access_token: accessToken,
    token_type: 'Bearer',
    expires_in: '24h'
  };

  if (refreshToken) {
    response.refresh_token = refreshToken;
  }

  return response;
};

/**
 * Kiểm tra token có hết hạn không
 * @param {string} token - JWT token
 * @returns {boolean} True nếu token hết hạn
 */
const isTokenExpired = (token) => {
  try {
    const decoded = jwt.decode(token);
    if (!decoded || !decoded.exp) return true;
    
    const currentTime = Math.floor(Date.now() / 1000);
    return decoded.exp < currentTime;
  } catch (error) {
    return true;
  }
};

/**
 * Lấy thời gian hết hạn của token
 * @param {string} token - JWT token
 * @returns {Date|null} Thời gian hết hạn hoặc null
 */
const getTokenExpiration = (token) => {
  try {
    const decoded = jwt.decode(token);
    if (!decoded || !decoded.exp) return null;
    
    return new Date(decoded.exp * 1000);
  } catch (error) {
    return null;
  }
};

/**
 * Tạo random string cho reset password
 * @param {number} length - Độ dài string (default: 32)
 * @returns {string} Random string
 */
const generateRandomString = (length = 32) => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
};

/**
 * Tạo password reset token
 * @param {string} userId - User ID
 * @returns {string} Reset token
 */
const generatePasswordResetToken = (userId) => {
  const payload = {
    user_id: userId,
    type: 'password_reset',
    timestamp: Date.now()
  };
  
  return jwt.sign(payload, process.env.JWT_SECRET || 'your-secret-key', { expiresIn: '1h' });
};

/**
 * Verify password reset token
 * @param {string} token - Reset token
 * @returns {Object} Decoded payload
 */
const verifyPasswordResetToken = (token) => {
  return jwt.verify(token, process.env.JWT_SECRET || 'your-secret-key');
};

module.exports = {
  generateToken,
  verifyToken,
  hashPassword,
  comparePassword,
  createTokenPayload,
  extractTokenFromHeader,
  generateRefreshToken,
  verifyRefreshToken,
  createLoginResponse,
  isTokenExpired,
  getTokenExpiration,
  generateRandomString,
  generatePasswordResetToken,
  verifyPasswordResetToken
};
