import { User, Organization, AccessRequest, Role, Permission } from '@prisma/client';
import { v4 as uuidv4 } from 'uuid';

const randomString = (prefix: string = 'text') => `${prefix}-${Math.random().toString(36).substring(7)}`;
const randomEmail = () => `${randomString('user')}@example.com`;
const randomDate = () => new Date();

export class TestFactory {
    static createUser(overrides: Partial<User> = {}): User {
        return {
            id: overrides.id || uuidv4(),
            email: overrides.email || randomEmail(),
            username: overrides.username || randomString('user'),
            passwordHash: overrides.passwordHash || 'hashed-password',
            isActive: overrides.isActive ?? true,
            emailVerified: overrides.emailVerified ?? false,
            mfaEnabled: overrides.mfaEnabled ?? false,
            mfaSecret: overrides.mfaSecret || null,
            mfaBackupCodes: overrides.mfaBackupCodes || null,
            lastLoginAt: overrides.lastLoginAt || null,
            loginCount: overrides.loginCount ?? 0,
            failedLoginAttempts: overrides.failedLoginAttempts ?? 0,
            lockedUntil: overrides.lockedUntil || null,
            organizationId: overrides.organizationId || null,
            createdAt: overrides.createdAt || randomDate(),
            updatedAt: overrides.updatedAt || randomDate(),
            ...overrides,
        };
    }

    static createOrganization(overrides: Partial<Organization> = {}): Organization {
        return {
            id: overrides.id || uuidv4(),
            name: overrides.name || randomString('org'),
            domain: overrides.domain || `${randomString('org')}.com`,
            parentId: overrides.parentId || null,
            settings: overrides.settings || {},
            isActive: overrides.isActive ?? true,
            createdAt: overrides.createdAt || randomDate(),
            updatedAt: overrides.updatedAt || randomDate(),
            ...overrides,
        };
    }

    static createRole(overrides: Partial<Role> = {}): Role {
        return {
            id: overrides.id || uuidv4(),
            name: overrides.name || randomString('ROLE').toUpperCase(),
            displayName: overrides.displayName || randomString('Role Name'),
            description: overrides.description || randomString('Description'),
            isSystem: overrides.isSystem ?? false,
            createdAt: overrides.createdAt || randomDate(),
            updatedAt: overrides.updatedAt || randomDate(),
            ...overrides,
        };
    }

    static createPermission(overrides: Partial<Permission> = {}): Permission {
        return {
            id: overrides.id || uuidv4(),
            resource: overrides.resource || 'users',
            action: overrides.action || 'create',
            scope: overrides.scope || 'all',
            description: overrides.description || randomString('desc'),
            createdAt: overrides.createdAt || randomDate(),
            ...overrides,
        };
    }

    static createAccessRequest(overrides: Partial<AccessRequest> = {}): AccessRequest {
        return {
            id: overrides.id || uuidv4(),
            userId: overrides.userId || uuidv4(),
            resource: overrides.resource || 'resource',
            action: overrides.action || 'read',
            reason: overrides.reason || randomString('reason'),
            status: overrides.status || 'PENDING',
            requestedAt: overrides.requestedAt || randomDate(),
            reviewedAt: overrides.reviewedAt || null,
            reviewedBy: overrides.reviewedBy || null,
            expiresAt: overrides.expiresAt || null,
            metadata: overrides.metadata || {},
            ...overrides,
        };
    }
}
