import { sendEmail } from '../common/utils/email.service.js';
import { getProspectPortalUrl } from '../common/utils/frontendUrl.js';
import db from '../database/models/index.js';
const { Notification, PushSubscription } = db;

/**
 * Global Notification Service to handle Email, WhatsApp, and Push Notifications.
 * This satisfies the SRS v2.0 requirement for centralized communication logic.
 */
export class NotificationService {
    /**
     * Sends a unified notification across multiple channels
     */
    static async notify(userId: string | null, email: string | null, data: {
        title: string,
        message: string,
        channels: ('email' | 'whatsapp' | 'push' | 'system')[],
        templateCode?: string,
        placeholders?: any,
        metadata?: any
    }) {
        const { title, message, channels, templateCode, placeholders, metadata } = data;

        // 1. System Notification (In-app) - Always synchronous for immediate feedback
        if (channels.includes('system') && userId) {
            try {
                const notification = await Notification.create({
                    userId,
                    title,
                    message,
                    type: metadata?.type || 'info',
                    link: placeholders?.link || metadata?.link || null,
                    isRead: false
                });

                // Emit realtime update via Socket.io
                const { getIO } = await import('../common/utils/socket.js');
                const io = getIO();
                if (io) {
                    const roomName = `user_${userId}`;
                    io.to(roomName).emit('notification', {
                        id: notification.id,
                        title,
                        message,
                        type: notification.type,
                        link: notification.link,
                        createdAt: notification.createdAt
                    });
                }
            } catch (err) {
                console.error('[NotificationService] Failed to create system notification:', err);
            }
        }

        // 2. Offload other channels to Job Queue (BullMQ) or Send Synchronously if Redis is disabled
        const asyncChannels = channels.filter(c => c !== 'system');
        if (asyncChannels.length > 0) {
            if (process.env.ENABLE_REDIS === 'true') {
                const { addNotificationJob } = await import('../common/queues/notification.queue.js');
                await addNotificationJob({
                    userId,
                    email,
                    title,
                    message,
                    channels: asyncChannels,
                    templateCode,
                    placeholders,
                    metadata
                });
            } else {
                console.log(`[Notification Service] Redis disabled. Sending ${asyncChannels.join(', ')} synchronously...`);
                // Fallback: Process immediately if queueing is disabled
                await this.processJob({
                    userId,
                    email,
                    title,
                    message,
                    channels: asyncChannels,
                    templateCode,
                    placeholders,
                    metadata
                });
            }
        }
    }

    /**
     * Processor for BullMQ jobs
     */
    static async processJob(jobData: any) {
        const { userId, email, title, message, channels, templateCode, placeholders, metadata } = jobData;

        for (const channel of channels) {
            try {
                if (channel === 'email' && email) {
                    await sendEmail(email, title, templateCode || 'GENERIC_NOTIFICATION', {
                        ...placeholders,
                        title,
                        message
                    });
                } else if (channel === 'whatsapp') {
                    const phoneNumber = placeholders?.phone || placeholders?.mobileNumber || 'Unknown';
                    await this.sendWhatsApp(phoneNumber, templateCode || 'generic_msg', placeholders);
                } else if (channel === 'push' && userId) {
                    await this.sendPush(userId, title, message, metadata);
                }
            } catch (error) {
                console.error(`[Notification Service] Failed to process ${channel} for ${userId || email}:`, error);
                throw error; // Re-throw to trigger BullMQ retry
            }
        }
    }

    /**
     * Mock WhatsApp integration as requested in SRS
     */
    static async sendWhatsApp(to: string, templateCode: string, placeholders: any) {
        // Log to console for audit during dev/mock phase
        console.log(`[WhatsApp Service] Triggered for ${to} using template ${templateCode}`);
        console.log(`[WhatsApp Service] Payload:`, placeholders);
        
        // In reality, this would call Meta's WhatsApp Business API or Twilio
        // return await WhatsAppAPI.send(to, templateCode, placeholders);
        return true;
    }

    /**
     * Web Push Notification logic
     */
    private static async sendPush(userId: string, title: string, message: string, metadata: any) {
        try {
            const subscriptions = await PushSubscription.findAll({ where: { userId } });
            if (subscriptions.length === 0) return;

            console.log(`[Push Service] Sending ${subscriptions.length} push notifications to User: ${userId}`);
            // Integration with web-push library would go here
        } catch (error) {
            console.error('[Push Service] Error:', error);
        }
    }

    /**
     * Specific Trigger: Questionnaire Reminder
     */
    static async sendQuestionnaireReminder(
        email: string,
        phone: string,
        applicantName: string,
        options?: { location?: string; link?: string }
    ) {
        await this.notify(null, email, {
            title: 'Action Required: Complete your Dealership Questionnaire',
            message: `Hi ${applicantName}, please complete the questionnaire to proceed with your application.`,
            channels: ['email', 'whatsapp'],
            templateCode: 'QUESTIONNAIRE_REMINDER',
            placeholders: {
                applicantName,
                phone,
                location: options?.location ?? '',
                link: options?.link ?? getProspectPortalUrl(),
                ctaLabel: 'Complete Questionnaire'
            }
        });
    }

    /**
     * Reminder for pending onboarding document uploads (bulk or scheduled send).
     */
    static async sendDocumentSubmissionReminder(
        email: string,
        phone: string | null | undefined,
        applicantName: string,
        options: { applicationId: string; pendingDocuments?: string; dueDate?: string; link?: string }
    ) {
        const channels: ('email' | 'whatsapp')[] = ['email'];
        if (phone) channels.push('whatsapp');
        await this.notify(null, email, {
            title: `Reminder: Pending documents — ${options.applicationId}`,
            message: `Hi ${applicantName}, please upload pending documents for ${options.applicationId}.`,
            channels,
            templateCode: 'DOCUMENT_SUBMISSION_REMINDER',
            placeholders: {
                applicantName,
                applicationId: options.applicationId,
                pendingDocuments:
                    options.pendingDocuments ||
                    'Please sign in to the Dealer Portal to view your personalised document checklist.',
                dueDate: options.dueDate || 'within seven calendar days',
                link: options.link || getProspectPortalUrl(),
                ctaLabel: 'Upload documents',
                phone: phone || ''
            }
        });
    }

    /**
     * Chase applicant to acknowledge issued LOI (bulk send from DD-Admin).
     */
    static async sendLoiAcknowledgementReminder(
        email: string,
        phone: string | null | undefined,
        applicantName: string,
        options: { applicationId: string; link?: string; dueDate?: string }
    ) {
        const channels: ('email' | 'whatsapp')[] = ['email'];
        if (phone) channels.push('whatsapp');
        await this.notify(null, email, {
            title: `Acknowledge your LOI — ${options.applicationId}`,
            message: `Hi ${applicantName}, your Letter of Intent is awaiting acknowledgement on the portal.`,
            channels,
            templateCode: 'LOI_ACKNOWLEDGEMENT_REQUEST',
            placeholders: {
                applicantName,
                applicationId: options.applicationId,
                dueDate: options.dueDate || 'within seven calendar days',
                link: options.link || getProspectPortalUrl(),
                ctaLabel: 'Acknowledge LOI',
                phone: phone || ''
            }
        });
    }
}
