import { describe, it, expect, vi, beforeEach } from "vitest";
import { appRouter } from "./routers";
import type { TrpcContext } from "./_core/context";

// ── Mock nodemailer ───────────────────────────────────────────────────────────
const sendMailMock = vi.fn().mockResolvedValue({ messageId: "test-id" });

vi.mock("nodemailer", () => ({
  default: {
    createTransport: vi.fn(() => ({
      sendMail: sendMailMock,
    })),
  },
}));

// ── Minimal public context ────────────────────────────────────────────────────
function createPublicContext(): TrpcContext {
  return {
    user: null,
    req: { protocol: "https", headers: {} } as TrpcContext["req"],
    res: {
      clearCookie: vi.fn(),
    } as unknown as TrpcContext["res"],
  };
}

describe("contact.send", () => {
  beforeEach(() => {
    sendMailMock.mockClear();
    process.env.SMTP_HOST = "mail.starhero24.com";
    process.env.SMTP_PORT = "465";
    process.env.SMTP_USER = "kontakt@starhero24.com";
    process.env.SMTP_PASS = "test-pass";
    process.env.SMTP_TO = "kontakt@starhero24.com";
  });

  it("sends two emails (notification + confirmation) and returns success", async () => {
    const ctx = createPublicContext();
    const caller = appRouter.createCaller(ctx);

    const result = await caller.contact.send({
      name: "Max Mustermann",
      company: "Muster GmbH",
      email: "max@beispiel.de",
      phone: "+49 30 123456",
      reviewCount: "1-3",
      message: "Ich habe 2 negative Bewertungen.",
    });

    expect(result).toEqual({ success: true });
    // Should send exactly 2 emails: one to owner, one confirmation to customer
    expect(sendMailMock).toHaveBeenCalledTimes(2);

    const [ownerMail, confirmMail] = sendMailMock.mock.calls;
    // Owner notification
    expect(ownerMail[0].to).toBe("kontakt@starhero24.com");
    expect(ownerMail[0].subject).toContain("Max Mustermann");
    // Customer confirmation
    expect(confirmMail[0].to).toBe("max@beispiel.de");
    expect(confirmMail[0].subject).toContain("Bestätigung");
  });

  it("validates required fields – rejects empty name", async () => {
    const ctx = createPublicContext();
    const caller = appRouter.createCaller(ctx);

    await expect(
      caller.contact.send({
        name: "",
        email: "max@beispiel.de",
      })
    ).rejects.toThrow();
  });

  it("validates email format", async () => {
    const ctx = createPublicContext();
    const caller = appRouter.createCaller(ctx);

    await expect(
      caller.contact.send({
        name: "Max",
        email: "not-an-email",
      })
    ).rejects.toThrow();
  });
});
