/**
 * Quotation Notifier Service
 *
 * Channel-agnostic notification dispatcher.
 * Called by dispatchQuotation and sendQuotationReminder.
 *
 * Sends:
 * - Email with PDF attachment (if customer has email)
 * - WhatsApp text with payment link (if customer has phone AND org has Twilio creds)
 *
 * All delivery failures are non-blocking.
 */

import { prisma } from '@/lib/db';
import { logger } from '@/lib/logger';
import { sendEmailImmediate } from '@/lib/services/email/core';
import { generateQuotationPdf } from '@/lib/services/quotation-pdf.service';
import { twilioWhatsAppService } from '@/lib/services/twilio-whatsapp.service';
import {
  createQuotationSentEmail,
  createQuotationReminderEmail,
  createQuotationOverdueEmail,
} from '@/lib/services/email/templates/quotation-templates';

const log = logger.scope('QuotationNotifier');

// ═══════════════════════════════════════════════════════════════════════
// Types
// ═══════════════════════════════════════════════════════════════════════

export type NotificationType = 'dispatch' | 'reminder' | 'overdue';

export interface NotifierQuotation {
  id: string;
  userId: string;
  quotationNumber: string;
  title: string;
  total: number;
  amountPaid: number;
  currency: string;
  dueDate?: Date | null;
  portalToken?: string | null;
  createdAt: Date;
  taxRate?: number | null;
  discountRate?: number | null;
  penaltyAmount?: number | null;
  customer?: {
    name?: string | null;
    email?: string | null;
    phone?: string | null;
  } | null;
  items?: Array<{
    description: string;
    quantity: number;
    unitPrice: number;
    total: number;
  }>;
}

export interface NotifyResult {
  emailQueued: boolean;
  whatsappSent: boolean;
}

// ═══════════════════════════════════════════════════════════════════════
// Main function
// ═══════════════════════════════════════════════════════════════════════

export async function notifyQuotationCustomer(
  quotation: NotifierQuotation,
  type: NotificationType,
): Promise<NotifyResult> {
  const baseUrl = process.env.NEXTAUTH_URL ?? 'http://localhost:9000';
  const portalUrl = quotation.portalToken
    ? `${baseUrl}/quotation/${quotation.portalToken}`
    : `${baseUrl}/dashboard`;

  // 1. Generate PDF (non-blocking on failure)
  let pdfBuffer: Buffer | null = null;
  try {
    pdfBuffer = await generateQuotationPdf({
      quotationNumber: quotation.quotationNumber,
      title:           quotation.title,
      createdAt:       quotation.createdAt,
      dueDate:         quotation.dueDate,
      total:           quotation.total,
      currency:        quotation.currency,
      taxRate:         quotation.taxRate,
      discountRate:    quotation.discountRate,
      portalToken:     quotation.portalToken,
      customer:        quotation.customer,
      items:           quotation.items,
    });
  } catch (err) {
    log.warn('PDF generation failed — sending without attachment', { quotationId: quotation.id, err });
  }

  // 2. Email
  let emailQueued = false;
  const customerEmail = quotation.customer?.email;
  if (customerEmail) {
    try {
      const lang = 'en';
      const dueDate = quotation.dueDate?.toLocaleDateString('en-GB') ?? '';
      const daysUntilDue = quotation.dueDate
        ? Math.ceil((quotation.dueDate.getTime() - Date.now()) / 86_400_000)
        : 0;
      const remaining = quotation.total - quotation.amountPaid;

      let template;
      if (type === 'dispatch') {
        template = createQuotationSentEmail({
          quotationNumber: quotation.quotationNumber,
          title:           quotation.title,
          customerName:    quotation.customer?.name ?? 'Customer',
          total:           quotation.total,
          currency:        quotation.currency,
          dueDate,
          portalUrl,
          items:           quotation.items ?? [],
          lang,
        });
      } else if (type === 'reminder') {
        template = createQuotationReminderEmail({
          quotationNumber: quotation.quotationNumber,
          customerName:    quotation.customer?.name ?? 'Customer',
          total:           quotation.total,
          amountPaid:      quotation.amountPaid,
          remaining,
          dueDate,
          daysUntilDue,
          portalUrl,
          lang,
        });
      } else {
        template = createQuotationOverdueEmail({
          quotationNumber: quotation.quotationNumber,
          customerName:    quotation.customer?.name ?? 'Customer',
          total:           quotation.total,
          amountPaid:      quotation.amountPaid,
          penaltyAmount:   quotation.penaltyAmount ?? 0,
          grandTotal:      quotation.total + (quotation.penaltyAmount ?? 0),
          dueDate,
          daysOverdue:     Math.abs(daysUntilDue),
          portalUrl,
          lang,
        });
      }

      const attachments = pdfBuffer
        ? [
            {
              filename: `quotation-${quotation.quotationNumber}.pdf`,
              content:  pdfBuffer.toString('base64'),
              encoding: 'base64' as const,
            },
          ]
        : [];

      emailQueued = await sendEmailImmediate(customerEmail, {
        subject:     template.subject,
        html:        template.html,
        text:        template.text,
        attachments: attachments.length > 0 ? attachments : undefined,
      });
    } catch (err) {
      log.warn('Failed to enqueue quotation email', { quotationId: quotation.id, type, err });
    }
  }

  // 3. WhatsApp
  let whatsappSent = false;
  const customerPhone = quotation.customer?.phone;
  if (customerPhone) {
    try {
      const org = await prisma.organizations.findUnique({
        where:  { ownerId: quotation.userId },
        select: { id: true },
      });

      if (org) {
        const creds = await twilioWhatsAppService.getCredentialsForOrg(org.id);

        if (creds) {
          const remaining  = (quotation.total - quotation.amountPaid).toFixed(2);
          const dueDate    = quotation.dueDate?.toLocaleDateString('en-GB') ?? '';
          const daysOverdue = quotation.dueDate
            ? Math.abs(Math.ceil((quotation.dueDate.getTime() - Date.now()) / 86_400_000))
            : 0;

          let body: string;
          if (type === 'dispatch') {
            body = [
              `📋 New Quotation #${quotation.quotationNumber} — ${quotation.title}`,
              `Total: ${quotation.currency} ${quotation.total.toFixed(2)}`,
              `View & Pay: ${portalUrl}`,
            ].join('\n');
          } else if (type === 'reminder') {
            body = [
              `⏰ Payment Reminder — Quotation #${quotation.quotationNumber}`,
              `Due: ${dueDate}  |  Remaining: ${quotation.currency} ${remaining}`,
              `Pay now: ${portalUrl}`,
            ].join('\n');
          } else {
            const amountDue = (quotation.total + (quotation.penaltyAmount ?? 0) - quotation.amountPaid).toFixed(2);
            const penaltySuffix = quotation.penaltyAmount ? ' (incl. penalty)' : '';
            body = [
              `🚨 Payment Overdue — Quotation #${quotation.quotationNumber}`,
              `${daysOverdue} day${daysOverdue !== 1 ? 's' : ''} past due`,
              `Amount due: ${quotation.currency} ${amountDue}${penaltySuffix}`,
              `Pay now: ${portalUrl}`,
            ].join('\n');
          }

          const result = await twilioWhatsAppService.sendTextMessage(
            creds,
            `whatsapp:${customerPhone}`,
            body,
          );

          whatsappSent = result.success;
          if (!result.success) {
            log.warn('WhatsApp send failed', { quotationId: quotation.id, error: result.error });
          }
        }
      }
    } catch (err) {
      log.warn('Failed to send WhatsApp notification', { quotationId: quotation.id, type, err });
    }
  }

  log.info('Quotation notification sent', { quotationId: quotation.id, type, emailQueued, whatsappSent });
  return { emailQueued, whatsappSent };
}
