import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { JWTPayload, User } from '../types';

const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d';

export async function hashPassword(password: string): Promise<string> {
  return bcrypt.hash(password, 10);
}

export async function comparePassword(
  password: string,
  hash: string
): Promise<boolean> {
  return bcrypt.compare(password, hash);
}

export function generateToken(user: User): string {
  const payload: JWTPayload = {
    userId: user.id,
    email: user.email,
    plan: user.plan,
  };

  return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN as jwt.SignOptions['expiresIn'] });
}

export function verifyToken(token: string): JWTPayload {
  return jwt.verify(token, JWT_SECRET) as JWTPayload;
}

export function validateEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

export function validatePassword(password: string): {
  valid: boolean;
  errors: string[];
} {
  const errors: string[] = [];

  if (password.length < 8) {
    errors.push('Password must be at least 8 characters long');
  }

  if (!/[A-Z]/.test(password)) {
    errors.push('Password must contain at least one uppercase letter');
  }

  if (!/[a-z]/.test(password)) {
    errors.push('Password must contain at least one lowercase letter');
  }

  if (!/[0-9]/.test(password)) {
    errors.push('Password must contain at least one number');
  }

  return {
    valid: errors.length === 0,
    errors,
  };
}

export function generatePasswordResetToken(email: string): string {
  return jwt.sign({ email, type: 'password-reset' }, JWT_SECRET, { expiresIn: '1h' });
}

export function verifyPasswordResetToken(token: string): { email: string } {
  try {
    const decoded = jwt.verify(token, JWT_SECRET) as { email: string; type: string };
    if (decoded.type !== 'password-reset') {
      throw new Error('Invalid token type');
    }
    return { email: decoded.email };
  } catch (error) {
    throw new Error('Invalid or expired reset token');
  }
}

export function generateEmailVerificationToken(email: string): string {
  return jwt.sign({ email, type: 'email-verification' }, JWT_SECRET, { expiresIn: '24h' });
}

export function verifyEmailVerificationToken(token: string): { email: string } {
  try {
    const decoded = jwt.verify(token, JWT_SECRET) as { email: string; type: string };
    if (decoded.type !== 'email-verification') {
      throw new Error('Invalid token type');
    }
    return { email: decoded.email };
  } catch (error) {
    throw new Error('Invalid or expired verification token');
  }
}
