import { Injectable } from '@nestjs/common'; import { IntegrationStrategy } from '../strategies/integration.strategy'; import { EmailFactory } from './email.factory'; import { SmsFactory } from './sms.factory'; import { WhatsAppFactory } from './whatsapp.factory'; import { TelephoneFactory } from './telephone.factory'; export enum IntegrationMode { EMAIL = 'EMAIL', SMS = 'SMS', WA = 'WA', TELEPHONE = 'TELEPHONE', } @Injectable() export class IntegrationFactory { private readonly modeFactoryMap = new Map(); constructor( private emailFactory: EmailFactory, private smsFactory: SmsFactory, private whatsappFactory: WhatsAppFactory, private telephoneFactory: TelephoneFactory, ) { this.initializeFactoryMap(); } private initializeFactoryMap(): void { this.modeFactoryMap.set(IntegrationMode.EMAIL, this.emailFactory); this.modeFactoryMap.set(IntegrationMode.SMS, this.smsFactory); this.modeFactoryMap.set(IntegrationMode.WA, this.whatsappFactory); this.modeFactoryMap.set(IntegrationMode.TELEPHONE, this.telephoneFactory); } create( mode: string, service: string, provider: string, ): IntegrationStrategy { const integrationMode = mode.toUpperCase() as IntegrationMode; if (!Object.values(IntegrationMode).includes(integrationMode)) { throw new Error(`Unsupported integration mode: ${mode}`); } const factory = this.modeFactoryMap.get(integrationMode); if (!factory) { throw new Error(`Factory not found for mode: ${mode}`); } return factory.createProvider(service, provider); } getAllSupportedCombinations(): Array<{ mode: string; service: string; provider: string; }> { const combinations: Array<{ mode: string; service: string; provider: string; }> = []; this.modeFactoryMap.forEach((factory, mode) => { const factoryCombinations = factory.getSupportedCombinations(); factoryCombinations.forEach((combo) => { combinations.push({ mode: mode, service: combo.service, provider: combo.provider, }); }); }); return combinations; } getSupportedCombinationsForMode( mode: string, ): Array<{ service: string; provider: string }> { const integrationMode = mode.toUpperCase() as IntegrationMode; const factory = this.modeFactoryMap.get(integrationMode); if (!factory) { throw new Error(`Factory not found for mode: ${mode}`); } return factory.getSupportedCombinations(); } validateCombination( mode: string, service: string, provider: string, ): boolean { try { const integrationMode = mode.toUpperCase() as IntegrationMode; const factory = this.modeFactoryMap.get(integrationMode); if (!factory) { return false; } return factory.validateCombination(service, provider); } catch { return false; } } getAvailableModes(): string[] { return Object.values(IntegrationMode); } getProvidersByModeAndService(mode: string, service: string): string[] { const combinations = this.getSupportedCombinationsForMode(mode); return combinations .filter((combo) => combo.service.toLowerCase() === service.toLowerCase()) .map((combo) => combo.provider); } }