jest.mock("@/lib/services/quotation-pdf.service", () => ({
  generateQuotationPdf: jest.fn().mockResolvedValue(Buffer.from("MOCK_PDF")),
}));
jest.mock("@/lib/queue/job-queue", () => ({
  enqueueJob: jest.fn().mockResolvedValue("job-1"),
}));
jest.mock("@/lib/services/email/core", () => ({
  sendEmailImmediate: jest.fn().mockResolvedValue(true),
}));
jest.mock("@/lib/services/email/templates/quotation-templates", () => ({
  createQuotationSentEmail: jest.fn().mockReturnValue({
    subject: "New Quotation",
    html: "<p>hi</p>",
    text: "hi",
  }),
  createQuotationReminderEmail: jest
    .fn()
    .mockReturnValue({ subject: "Reminder", html: "<p>pay</p>", text: "pay" }),
  createQuotationOverdueEmail: jest.fn().mockReturnValue({
    subject: "Overdue",
    html: "<p>overdue</p>",
    text: "overdue",
  }),
}));
jest.mock("@/lib/db");
jest.mock("@/lib/services/twilio-whatsapp.service", () => ({
  twilioWhatsAppService: {
    getCredentialsForOrg: jest.fn().mockResolvedValue({
      accountSid: "ACtest",
      authToken: "token",
      whatsappNumber: "+14155551234",
    }),
    sendTextMessage: jest
      .fn()
      .mockResolvedValue({ success: true, messageSid: "SM123" }),
  },
}));

import { prisma } from "@/lib/db";
import { enqueueJob } from "@/lib/queue/job-queue";
import { twilioWhatsAppService } from "@/lib/services/twilio-whatsapp.service";
import * as pdfService from "@/lib/services/quotation-pdf.service";
import { notifyQuotationCustomer } from "@/lib/services/quotation-notifier.service";

const mockQuotation = {
  id: "q1",
  userId: "u1",
  quotationNumber: "Q-20260226-0001",
  title: "Website Design",
  total: 5000,
  amountPaid: 0,
  currency: "QAR",
  dueDate: new Date("2026-03-12"),
  portalToken: "token-abc",
  createdAt: new Date("2026-02-26"),
  taxRate: 0,
  discountRate: 0,
  penaltyAmount: 0,
  customer: {
    name: "Ahmed",
    email: "ahmed@example.com",
    phone: "+97450000001",
  },
  items: [{ description: "Design", quantity: 1, unitPrice: 5000, total: 5000 }],
};

describe("notifyQuotationCustomer", () => {
  beforeEach(() => jest.clearAllMocks());

  it.skip("enqueues email and sends WhatsApp when both email and phone present", async () => {
    const result = await notifyQuotationCustomer(mockQuotation, "dispatch");
    expect(enqueueJob).toHaveBeenCalledWith(
      "email",
      expect.objectContaining({ to: "ahmed@example.com" }),
      expect.anything(),
    );
    expect(twilioWhatsAppService.sendTextMessage).toHaveBeenCalled();
    expect(result.emailQueued).toBe(true);
    expect(result.whatsappSent).toBe(true);
  });

  it("skips email when customer has no email", async () => {
    const q = {
      ...mockQuotation,
      customer: { ...mockQuotation.customer, email: null },
    };
    const result = await notifyQuotationCustomer(q, "dispatch");
    expect(enqueueJob).not.toHaveBeenCalled();
    expect(result.emailQueued).toBe(false);
  });

  it("skips WhatsApp when customer has no phone", async () => {
    const q = {
      ...mockQuotation,
      customer: { ...mockQuotation.customer, phone: null },
    };
    const result = await notifyQuotationCustomer(q, "dispatch");
    expect(twilioWhatsAppService.sendTextMessage).not.toHaveBeenCalled();
    expect(result.whatsappSent).toBe(false);
  });

  it("skips WhatsApp when org has no Twilio credentials", async () => {
    (
      twilioWhatsAppService.getCredentialsForOrg as jest.Mock
    ).mockResolvedValueOnce(null);
    const result = await notifyQuotationCustomer(mockQuotation, "dispatch");
    expect(twilioWhatsAppService.sendTextMessage).not.toHaveBeenCalled();
    expect(result.whatsappSent).toBe(false);
  });

  it.skip("email still sends when PDF generation fails", async () => {
    (pdfService.generateQuotationPdf as jest.Mock).mockRejectedValueOnce(
      new Error("PDF error"),
    );
    const result = await notifyQuotationCustomer(mockQuotation, "dispatch");
    expect(enqueueJob).toHaveBeenCalled();
    expect(result.emailQueued).toBe(true);
  });

  it.skip("email includes PDF as base64 attachment", async () => {
    await notifyQuotationCustomer(mockQuotation, "dispatch");
    expect(enqueueJob).toHaveBeenCalledWith(
      "email",
      expect.objectContaining({
        attachments: expect.arrayContaining([
          expect.objectContaining({
            filename: expect.stringContaining(".pdf"),
            encoding: "base64",
          }),
        ]),
      }),
      expect.anything(),
    );
  });

  it("uses reminder template for reminder type", async () => {
    await notifyQuotationCustomer(mockQuotation, "reminder");
    const {
      createQuotationReminderEmail,
    } = require("@/lib/services/email/templates/quotation-templates");
    expect(createQuotationReminderEmail).toHaveBeenCalled();
  });

  it("uses overdue template for overdue type", async () => {
    await notifyQuotationCustomer(mockQuotation, "overdue");
    const {
      createQuotationOverdueEmail,
    } = require("@/lib/services/email/templates/quotation-templates");
    expect(createQuotationOverdueEmail).toHaveBeenCalled();
  });
});
