import * as jwt from 'jsonwebtoken';
import * as bcrypt from 'bcryptjs';
import * as dotenv from 'dotenv';

dotenv.config();

const JWT_SECRET = process.env.JWT_SECRET || '';
const JWT_REFRESH_SECRET = process.env.JWT_REFRESH_SECRET || '';

export type TokenUser = {
  id: string;
  email?: string;
  firstname?: string;
  lastname?: string;
  role?: string;
  tokenVersion?: number;
};

export class encrypt {
  static async encryptpass(password: string) {
    return bcrypt.hashSync(password, 12);
  }

  static comparepassword(hashPassword: string, password: string) {
    return bcrypt.compareSync(password, hashPassword);
  }

  static generateAccessToken(payload: TokenUser) {
    return jwt.sign(payload, JWT_SECRET, { expiresIn: '1h' });
  }

  static generateRefreshToken(payload: Pick<TokenUser, 'id' | 'tokenVersion'>) {
    return jwt.sign(
      { id: payload.id, tokenVersion: payload.tokenVersion ?? 0 },
      JWT_REFRESH_SECRET,
      { expiresIn: '7d' }
    );
  }

  static verifyRefreshToken(token: string) {
    return jwt.verify(token, JWT_REFRESH_SECRET) as { id: string; tokenVersion?: number };
  }

  static generateTokenPair(user: {
    _id: unknown;
    email?: string;
    firstname?: string;
    lastname?: string;
    role?: string;
    tokenVersion?: number;
  }) {
    const payload: TokenUser = {
      id: String(user._id),
      email: user.email,
      firstname: user.firstname,
      lastname: user.lastname,
      role: user.role,
      tokenVersion: user.tokenVersion ?? 0,
    };

    return {
      token: encrypt.generateAccessToken(payload),
      refreshToken: encrypt.generateRefreshToken({
        id: payload.id,
        tokenVersion: payload.tokenVersion,
      }),
    };
  }

  /** @deprecated Use generateAccessToken */
  static generateToken(payload: TokenUser) {
    return encrypt.generateAccessToken(payload);
  }
}
