import { NotificationMessageProvider } from '#providers/NotificationMessageProvider';
import { Op } from 'sequelize';
import LoggingService from '#services/file-system/logService';

/**
 * Notification job for sending scheduled notifications
 * Processes pending scheduled notifications
 */

const logger = new LoggingService();

export class NotificationJob {
	static async run(): Promise<void> {
		try {
			logger.logInfoAsync('NotificationJob', new Error('Starting notification job'), null);

			// Get pending scheduled notifications
			const pendingNotifications = await NotificationJob.getPendingNotifications();

			// Process each notification
			for (const notification of pendingNotifications) {
				await NotificationJob.processNotification(notification);
			}

			logger.logInfoAsync(
				'NotificationJob',
				new Error(`Processed ${pendingNotifications.length} scheduled notifications`),
				null,
			);
		} catch (error) {
			logger.logErrorAsync('NotificationJob', error as Error, null);
			throw error;
		}
	}

	/**
	 * Get pending scheduled notifications
	 */
	private static async getPendingNotifications(): Promise<unknown[]> {
		const provider = NotificationMessageProvider.getInstance();
		const now = new Date();

		const { rows } = await provider.getAll({
			where: {
				scheduled_at: {
					[Op.lte]: now,
				},
			},
			pageSize: 100,
		});

		return rows;
	}

	/**
	 * Process a single scheduled notification
	 */
	private static async processNotification(notification: unknown): Promise<void> {
		const provider = NotificationMessageProvider.getInstance();

		try {
			// Send the notification
			// Note: This would need the actual notification data format
			logger.logInfoAsync(
				'NotificationJob',
				new Error(`Processing notification: ${(notification as { id: string }).id}`),
				null,
			);

			// Update notification - the new schema doesn't have is_sent or sent_time
			// Just update the updated_at timestamp to mark as processed
			await provider.updateById((notification as { id: string }).id, {
				updated_at: new Date(),
			});
		} catch (error) {
			logger.logErrorAsync(
				'NotificationJob',
				new Error(`Failed to process notification: ${(error as Error).message}`),
				null,
			);

			// Update notification with error in data field
			await provider.updateById((notification as { id: string }).id, {
				data: { error: (error as Error).message },
				updated_at: new Date(),
			});
		}
	}
}
