"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});exports.notificationQueue=exports.NotificationQueue=void 0;const bull_1=__importDefault(require("bull")),SendGridProvider_1=require("../providers/email/SendGridProvider"),NodemailerProvider_1=require("../providers/email/NodemailerProvider"),console_1=require("@b/utils/console");class NotificationQueue{constructor(){this.queue=new bull_1.default("notification-emails",{redis:{host:process.env.REDIS_HOST||"127.0.0.1",port:parseInt(process.env.REDIS_PORT||"6379"),password:process.env.REDIS_PASSWORD||void 0},defaultJobOptions:{attempts:3,backoff:{type:"exponential",delay:2e3},removeOnComplete:100,removeOnFail:500}});this.sendGridProvider=new SendGridProvider_1.SendGridProvider;this.nodemailerProvider=new NodemailerProvider_1.NodemailerProvider;this.queue.process(this.processEmailJob.bind(this));this.registerEventHandlers()}static getInstance(){NotificationQueue.instance||(NotificationQueue.instance=new NotificationQueue);return NotificationQueue.instance}async addEmailJob(e,o,i,t,r){try{const n=await this.queue.add({provider:e,emailData:o,notificationId:i,userId:t},{priority:r||0});console_1.logger.info("Queue",`Email job added to queue: ${n.id}`,{jobId:n.id,provider:e,notificationId:i,to:o.to});return n}catch(o){console_1.logger.error("Queue",`Failed to add email job to queue: provider=${e}, notificationId=${i}`,o instanceof Error?o:new Error(String(o)));throw o}}async processEmailJob(e){const{provider:o,emailData:i,notificationId:t,userId:r}=e.data;console_1.logger.info("Queue",`Processing email job: ${e.id}`,{jobId:e.id,provider:o,notificationId:t,attempt:e.attemptsMade+1});try{let r;if("sendgrid"===o)r=await this.sendGridProvider.send(i);else{if("nodemailer"!==o)throw new Error(`Unknown email provider: ${o}`);r=await this.nodemailerProvider.send(i)}if(!r.success)throw new Error(r.error||"Email send failed");console_1.logger.info("Queue",`Email job completed successfully: ${e.id}`,{jobId:e.id,provider:o,notificationId:t,messageId:r.messageId});return r}catch(i){console_1.logger.error("Queue",`Email job failed: jobId=${e.id}, provider=${o}, notificationId=${t}, attempt=${e.attemptsMade+1}`,i instanceof Error?i:new Error(String(i)));throw i}}registerEventHandlers(){this.queue.on("completed",(e,o)=>{console_1.logger.info("Queue",`Email job completed: ${e.id}`,{jobId:e.id,notificationId:e.data.notificationId,messageId:o.messageId})});this.queue.on("failed",(e,o)=>{console_1.logger.error("Queue",`Email job failed permanently: jobId=${e.id}, notificationId=${e.data.notificationId}, attempts=${e.attemptsMade}`,o instanceof Error?o:new Error(String(o)))});this.queue.on("stalled",e=>{console_1.logger.warn("Queue",`Email job stalled: jobId=${e.id}, notificationId=${e.data.notificationId}`)});this.queue.on("error",e=>{console_1.logger.error("Queue","Queue error occurred",e instanceof Error?e:new Error(String(e)))})}async getStats(){const[e,o,i,t,r]=await Promise.all([this.queue.getWaitingCount(),this.queue.getActiveCount(),this.queue.getCompletedCount(),this.queue.getFailedCount(),this.queue.getDelayedCount()]);return{waiting:e,active:o,completed:i,failed:t,delayed:r}}async getJob(e){return this.queue.getJob(e)}async retryFailedJob(e){const o=await this.queue.getJob(e);if(!o)throw new Error(`Job ${e} not found`);await o.retry();console_1.logger.info("Queue",`Retrying failed job: ${e}`)}async cleanOldJobs(e=864e5){const o=await this.queue.clean(e,"completed"),i=await this.queue.clean(e,"failed");console_1.logger.info("Queue",`Cleaned old jobs: ${o.length} completed, ${i.length} failed`);return[...o.map(e=>parseInt(e.id)),...i.map(e=>parseInt(e.id))]}async pause(){await this.queue.pause();console_1.logger.info("Queue","Queue paused")}async resume(){await this.queue.resume();console_1.logger.info("Queue","Queue resumed")}async close(){await this.queue.close();console_1.logger.info("Queue","Queue closed")}}exports.NotificationQueue=NotificationQueue;exports.notificationQueue=NotificationQueue.getInstance();