import { beforeEach, describe, expect, it, vi } from 'vitest';

const mocked = vi.hoisted(() => ({
  sendMail: vi.fn(async () => undefined),
  createTransport: vi.fn(() => ({ sendMail: mocked.sendMail })),
}));

vi.mock('nodemailer', () => ({
  default: {
    createTransport: mocked.createTransport,
  },
}));

describe('email service', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    process.env.FRONTEND_URL = 'https://rainmakersports.app';
  });

  it('sends a welcome email with survey and forecast deep links', async () => {
    const { sendWelcomeEmail } = await import('../email');

    await sendWelcomeEmail('fan@example.com');

    expect(mocked.sendMail).toHaveBeenCalledTimes(1);
    const sendMailMock = mocked.sendMail as any;
    const payload = sendMailMock.mock.calls[0][0] as any;
    expect(payload).toBeTruthy();
    expect(payload.to).toBe('fan@example.com');
    expect(payload.subject).toContain('Welcome to Rainmaker');
    expect(payload.html).toContain('https://rainmakersports.app/forecasts?welcome=true&survey=1');
    expect(payload.html).toContain('Claim My Free Forecasts');
    expect(payload.html).toContain('https://rainmakersports.app/forecasts?welcome=true');
    expect(payload.text).toContain('https://rainmakersports.app/forecasts?welcome=true&survey=1');
    expect(payload.text).toContain('https://rainmakersports.app/forecasts?welcome=true');
  });

  it('sends a monthly pass expiry email with a manual renew CTA', async () => {
    const { sendMonthlyPassExpiryEmail } = await import('../email');

    await sendMonthlyPassExpiryEmail('rain@example.com', {
      expiresAt: '2026-03-30T15:00:00.000Z',
    });

    expect(mocked.sendMail).toHaveBeenCalledTimes(1);
    const sendMailMock = mocked.sendMail as any;
    const payload = sendMailMock.mock.calls[0][0] as any;
    expect(payload.to).toBe('rain@example.com');
    expect(payload.subject).toContain('expires soon');
    expect(payload.html).toContain('This plan does not auto-renew');
    expect(payload.html).toContain('https://rainmakersports.app/pricing');
    expect(payload.text).toContain('Renew here: https://rainmakersports.app/pricing');
  });

  it('sends password reset links with the token in the URL fragment', async () => {
    const { sendPasswordResetEmail } = await import('../email');

    await sendPasswordResetEmail('fan@example.com', 'reset-token-123');

    expect(mocked.sendMail).toHaveBeenCalledTimes(1);
    const sendMailMock = mocked.sendMail as any;
    const payload = sendMailMock.mock.calls[0][0] as any;
    expect(payload.html).toContain('https://rainmakersports.app/reset-password#token=reset-token-123');
    expect(payload.html).not.toContain('/reset-password?token=');
    expect(payload.text).toContain('https://rainmakersports.app/reset-password#token=reset-token-123');
  });
});
