import bcrypt from 'bcryptjs' import jwt from 'jsonwebtoken' import { prisma } from '../../lib/prisma' const JWT_SECRET = process.env.JWT_SECRET ?? 'test-secret' let counter = 0 function uid() { return `${Date.now()}-${++counter}-${Math.random().toString(36).slice(2, 7)}` } export async function createCompanyWithEmployee(overrides: { role?: 'OWNER' | 'MANAGER' | 'AGENT' companyStatus?: 'ACTIVE' | 'TRIALING' | 'PAST_DUE' | 'SUSPENDED' | 'PENDING' } = {}) { const slug = `test-${uid()}` const company = await prisma.company.create({ data: { name: `Test Company ${slug}`, slug, email: `company-${slug}@test.com`, status: (overrides.companyStatus ?? 'ACTIVE') as any, subscription: { create: { status: 'TRIALING', plan: 'STARTER' }, }, }, }) const employee = await prisma.employee.create({ data: { companyId: company.id, clerkUserId: `clerk_${uid()}`, firstName: 'Test', lastName: 'User', email: `employee-${uid()}@test.com`, role: overrides.role ?? 'OWNER', }, }) return { company, employee } } export async function createVehicle(companyId: string, overrides: Record = {}) { return prisma.vehicle.create({ data: { companyId, make: 'Toyota', model: 'Corolla', year: 2022, color: 'White', licensePlate: `PL-${uid()}`, dailyRate: 500, status: 'AVAILABLE', isPublished: true, pickupLocations: ['Casablanca'], allowDifferentDropoff: false, dropoffLocations: [], ...overrides, } as any, }) } export async function createCustomer(companyId: string, overrides: Record = {}) { return prisma.customer.create({ data: { companyId, firstName: 'Jane', lastName: 'Doe', email: `customer-${uid()}@test.com`, ...overrides, }, }) } export async function createRenter(overrides: { firstName?: string lastName?: string email?: string password?: string isActive?: boolean } = {}) { return prisma.renter.create({ data: { firstName: overrides.firstName ?? 'Renter', lastName: overrides.lastName ?? 'User', email: overrides.email ?? `renter-${uid()}@test.com`, passwordHash: await bcrypt.hash(overrides.password ?? 'RenterPass123!', 10), isActive: overrides.isActive ?? true, }, }) } export async function createAdminUser(overrides: { email?: string firstName?: string lastName?: string password?: string role?: 'SUPER_ADMIN' | 'ADMIN' | 'SUPPORT' | 'FINANCE' | 'VIEWER' isActive?: boolean totpEnabled?: boolean totpSecret?: string | null } = {}) { return prisma.adminUser.create({ data: { email: overrides.email ?? `admin-${uid()}@test.com`, firstName: overrides.firstName ?? 'Admin', lastName: overrides.lastName ?? 'User', passwordHash: await bcrypt.hash(overrides.password ?? 'AdminPass123!', 10), role: (overrides.role ?? 'ADMIN') as any, isActive: overrides.isActive ?? true, totpEnabled: overrides.totpEnabled ?? false, totpSecret: overrides.totpSecret ?? null, }, }) } export async function createReservation( companyId: string, vehicleId: string, customerId: string, overrides: Record = {}, ) { return prisma.reservation.create({ data: { companyId, vehicleId, customerId, startDate: new Date(Date.now() + 24 * 60 * 60 * 1000), endDate: new Date(Date.now() + 4 * 24 * 60 * 60 * 1000), dailyRate: 500, totalDays: 3, totalAmount: 1500, depositAmount: 300, status: 'CONFIRMED', paymentStatus: 'UNPAID', paidAmount: 0, ...overrides, } as any, }) } export async function createRentalPayment( companyId: string, reservationId: string, overrides: Record = {}, ) { return prisma.rentalPayment.create({ data: { companyId, reservationId, amount: 500, currency: 'MAD', status: 'SUCCEEDED', type: 'CHARGE', paymentProvider: 'AMANPAY', amanpayTransactionId: `aman-${uid()}`, paidAt: new Date(), ...overrides, } as any, }) } export async function createSubscriptionInvoice( companyId: string, subscriptionId: string, overrides: Record = {}, ) { return prisma.subscriptionInvoice.create({ data: { companyId, subscriptionId, amount: 29900, currency: 'MAD', status: 'PENDING', paymentProvider: 'AMANPAY', amanpayTransactionId: `sub-${uid()}`, ...overrides, } as any, }) } export async function createCompanyNotification( companyId: string, employeeId?: string, overrides: Record = {}, ) { return prisma.notification.create({ data: { companyId, employeeId, type: 'PAYMENT_RECEIVED', title: 'Payment received', body: 'A payment was recorded.', channel: 'IN_APP', status: 'PENDING', ...overrides, } as any, }) } export async function createRenterNotification( renterId: string, overrides: Record = {}, ) { return prisma.notification.create({ data: { renterId, type: 'BOOKING_CONFIRMED', title: 'Booking confirmed', body: 'Your booking is confirmed.', channel: 'IN_APP', status: 'PENDING', ...overrides, } as any, }) } export function signEmployeeToken(employeeId: string, companyId: string, role: string = 'OWNER') { return jwt.sign( { sub: employeeId, companyId, role, type: 'employee' }, JWT_SECRET, { expiresIn: '1h' }, ) } export function signAdminToken(adminId: string) { return jwt.sign( { sub: adminId, type: 'admin' }, JWT_SECRET, { expiresIn: '1h' }, ) } export function signRenterToken(renterId: string) { return jwt.sign( { sub: renterId, type: 'renter' }, JWT_SECRET, { expiresIn: '1h' }, ) } export function authHeader(token: string) { return { Authorization: `Bearer ${token}` } }