/**
 * Authentication Helper for Tests
 *
 * Provides utility functions for authentication testing.
 */

import { sign } from 'jsonwebtoken';
import * as bcrypt from 'bcryptjs';

/**
 * Generate a test JWT access token
 */
export function generateTestAccessToken(
	payload: {
		id?: string;
		email?: string;
		username?: string;
		roles?: string[];
	} = {},
): string {
	const defaultPayload = {
		id: payload.id || '550e8400-e29b-41d4-a716-446655440000',
		email: payload.email || 'test@example.com',
		username: payload.username || 'testuser',
		roles: payload.roles || ['user'],
	};

	return sign(defaultPayload, process.env.JWT_SECRET!, {
		expiresIn: '15m',
		issuer: 'backend-template',
		audience: 'api-users',
	});
}

/**
 * Generate a test JWT refresh token
 */
export function generateTestRefreshToken(
	payload: {
		id?: string;
		email?: string;
		roles?: string[];
	} = {},
): string {
	const defaultPayload = {
		id: payload.id || '550e8400-e29b-41d4-a716-446655440000',
		email: payload.email || 'test@example.com',
		roles: payload.roles || ['user'],
		type: 'refresh',
	};

	return sign(defaultPayload, process.env.JWT_REFRESH_SECRET!, {
		expiresIn: '7d',
		issuer: 'backend-template',
		audience: 'api-users',
	});
}

/**
 * Hash a password for test users
 */
export async function hashTestPassword(password: string): Promise<string> {
	const rounds = parseInt(process.env.BCRYPT_ROUNDS || '4');
	return bcrypt.hash(password, rounds);
}

/**
 * Create authentication headers for API requests
 */
export function createAuthHeaders(token?: string): Record<string, string> {
	const accessToken = token || generateTestAccessToken();
	return {
		Authorization: `Bearer ${accessToken}`,
		'Content-Type': 'application/json',
	};
}

/**
 * Create cookie header with tokens
 */
export function createCookieHeader(accessToken?: string, refreshToken?: string): string {
	const cookies: string[] = [];

	if (accessToken) {
		cookies.push(`access_token=${accessToken}`);
	}

	if (refreshToken) {
		cookies.push(`refresh_token=${refreshToken}`);
	}

	return cookies.join('; ');
}

/**
 * Extract tokens from response cookies
 */
export function extractTokensFromCookies(
	cookies: string[]
): { accessToken?: string; refreshToken?: string } {
	const result: { accessToken?: string; refreshToken?: string } = {};

	for (const cookie of cookies) {
		const accessMatch = cookie.match(/access_token=([^;]+)/);
		if (accessMatch && accessMatch[1]) {
			result.accessToken = accessMatch[1];
		}

		const refreshMatch = cookie.match(/refresh_token=([^;]+)/);
		if (refreshMatch && refreshMatch[1]) {
			result.refreshToken = refreshMatch[1];
		}
	}

	return result;
}

/**
 * Verify password against hash (for test assertions)
 */
export async function verifyTestPassword(password: string, hash: string): Promise<boolean> {
	return bcrypt.compare(password, hash);
}
