const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
require('dotenv').config({ path: './config.env' });

const JWT_SECRET = process.env.JWT_SECRET || 'cfx_ui_super_secret_key_2024';
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d';

// Generate UUID v4
const generateUUID = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
};

// Hash password
const hashPassword = async (password) => {
  const saltRounds = 12;
  return await bcrypt.hash(password, saltRounds);
};

// Compare password
const comparePassword = async (password, hash) => {
  return await bcrypt.compare(password, hash);
};

// Generate JWT token
const generateToken = (payload) => {
  return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
};

// Verify JWT token
const verifyToken = (token) => {
  try {
    return jwt.verify(token, JWT_SECRET);
  } catch (error) {
    return null;
  }
};

// Generate 6-character verification token (letters + digits)
const generateVerificationToken = () => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  let result = '';
  for (let i = 0; i < 6; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
};

// Generate 6-character reset password token (letters + digits)
const generateResetPasswordToken = () => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  let result = '';
  for (let i = 0; i < 6; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
};

// Validate email format
const isValidEmail = (email) => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
};

// Validate password strength
const validatePassword = (password) => {
  if (password.length < 6) {
    return { isValid: false, message: 'Password must be at least 6 characters long' };
  }
  return { isValid: true };
};

// Validate username
const validateUsername = (username) => {
  if (username.length < 3) {
    return { isValid: false, message: 'Username must be at least 3 characters long' };
  }
  if (username.length > 50) {
    return { isValid: false, message: 'Username must not exceed 50 characters' };
  }
  const usernameRegex = /^[a-zA-Z0-9_]+$/;
  if (!usernameRegex.test(username)) {
    return { isValid: false, message: 'Username must only contain letters, numbers, and underscores' };
  }
  return { isValid: true };
};

// Sanitize user data for response
const sanitizeUser = (user) => {
  const { password_hash, verification_token, reset_password_token, reset_password_expires, ...sanitizedUser } = user;
  return sanitizedUser;
};

// Get client IP address
const getClientIP = (req) => {
  return req.headers['x-forwarded-for'] ||
    req.connection.remoteAddress ||
    req.socket.remoteAddress ||
    (req.connection.socket ? req.connection.socket.remoteAddress : null) ||
    req.ip;
};

// Get user agent
const getUserAgent = (req) => {
  return req.headers['user-agent'] || 'Unknown';
};

// Update profile validation middleware
const updateProfileValidation = (req, res, next) => {
  const { username, email } = req.body;
  const errors = [];

  if (username !== undefined) {
    const usernameValidation = validateUsername(username);
    if (!usernameValidation.isValid) {
      errors.push(usernameValidation.message);
    }
  }

  if (email !== undefined) {
    if (!isValidEmail(email)) {
      errors.push('Email is invalid');
    }
  }

  if (errors.length > 0) {
    return res.status(400).json({
      success: false,
      error: errors.join(', ')
    });
  }

  next();
};

// Handle validation errors middleware
const handleValidationErrors = (req, res, next) => {
  // This middleware is used as a placeholder for validation
  // The actual validation is done in the specific validation functions
  next();
};

module.exports = {
  generateUUID,
  hashPassword,
  comparePassword,
  generateToken,
  verifyToken,
  generateVerificationToken,
  generateResetPasswordToken,
  isValidEmail,
  validatePassword,
  validateUsername,
  sanitizeUser,
  getClientIP,
  getUserAgent,
  updateProfileValidation,
  handleValidationErrors
};
