const jwt = require('jsonwebtoken');

class JWTConfig {
  constructor() {
    this.accessTokenSecret = process.env.JWT_ACCESS_SECRET || 'access-secret-key-2024-tech4biz-secure_pipeline_2024';
    this.refreshTokenSecret = process.env.JWT_REFRESH_SECRET || 'refresh-secret-key-2024-tech4biz';
    this.accessTokenExpiry = process.env.JWT_ACCESS_EXPIRY || '24h';
    this.refreshTokenExpiry = process.env.JWT_REFRESH_EXPIRY || '7d';
    this.adminAccessTokenExpiry = process.env.JWT_ADMIN_ACCESS_EXPIRY || '7d'; // Extended expiry for admins
  }

  generateAccessToken(payload, isAdmin = false) {
    const expiry = isAdmin ? this.adminAccessTokenExpiry : this.accessTokenExpiry;
    return jwt.sign(payload, this.accessTokenSecret, {
      expiresIn: expiry,
      issuer: 'tech4biz-auth',
      audience: 'tech4biz-users'
    });
  }

  generateRefreshToken(payload) {
    return jwt.sign(payload, this.refreshTokenSecret, {
      expiresIn: this.refreshTokenExpiry,
      issuer: 'tech4biz-auth',
      audience: 'tech4biz-users'
    });
  }

  verifyAccessToken(token) {
    try {
      return jwt.verify(token, this.accessTokenSecret, {
        issuer: 'tech4biz-auth',
        audience: 'tech4biz-users'
      });
    } catch (error) {
      throw new Error('Invalid access token');
    }
  }

  verifyRefreshToken(token) {
    try {
      return jwt.verify(token, this.refreshTokenSecret, {
        issuer: 'tech4biz-auth',
        audience: 'tech4biz-users'
      });
    } catch (error) {
      throw new Error('Invalid refresh token');
    }
  }

  generateTokenPair(user) {
    const payload = {
      userId: user.id,
      email: user.email,
      username: user.username,
      role: user.role || 'user'
    };

    const isAdmin = user.role === 'admin' || user.role === 'super_admin';
    const accessToken = this.generateAccessToken(payload, isAdmin);
    const refreshToken = this.generateRefreshToken({ userId: user.id });
    const expiry = isAdmin ? this.adminAccessTokenExpiry : this.accessTokenExpiry;

    return {
      accessToken,
      refreshToken,
      expiresIn: expiry
    };
  }

  extractTokenFromHeader(authHeader) {
    if (!authHeader) {
      throw new Error('Authorization header missing');
    }

    if (!authHeader.startsWith('Bearer ')) {
      throw new Error('Invalid authorization header format');
    }

    return authHeader.substring(7); // Remove 'Bearer ' prefix
  }

  decodeToken(token) {
    try {
      return jwt.decode(token, { complete: true });
    } catch (error) {
      throw new Error('Invalid token format');
    }
  }

  getTokenExpiry(token) {
    const decoded = this.decodeToken(token);
    return decoded.payload.exp * 1000; // Convert to milliseconds
  }

  isTokenExpired(token) {
    try {
      const expiry = this.getTokenExpiry(token);
      return Date.now() >= expiry;
    } catch (error) {
      return true; // Treat invalid tokens as expired
    }
  }
}

module.exports = new JWTConfig();