import { POST } from '@/app/api/email/route';
import { NextRequest, NextResponse } from 'next/server';
import nodemailermock from '@/app/__tests__/__mocks__/nodemailer';

jest.mock('next/server', () => ({
  NextResponse: {
    json: jest.fn(),
  },
}));

beforeAll(() => {
  jest.spyOn(console, 'error').mockImplementation(() => {});
});

afterAll(() => {
  (console.error as jest.Mock).mockRestore();
});

beforeEach(() => {
  nodemailermock.mock.reset();
  process.env.MY_EMAIL = 'test@dki.one';
  process.env.MY_PASSWORD = 'test-password';
});

describe('POST /api/email', () => {
  it('should send an email', async () => {
    const mockRequest = {
      json: jest.fn().mockResolvedValue({
        email: 'test@example.com',
        name: 'Test User',
        subject: 'Test Subject',
        message: 'Hello! This is a test message.',
      }),
    } as unknown as NextRequest;

    await POST(mockRequest);

    expect(NextResponse.json).toHaveBeenCalledWith({ 
      message: "E-Mail erfolgreich gesendet",
      messageId: expect.any(String)
    });

    const sentEmails = nodemailermock.mock.getSentMail();
    expect(sentEmails.length).toBe(1);
    expect(sentEmails[0].to).toBe('contact@dki.one');
    expect(sentEmails[0].text).toContain('Hello! This is a test message.');
  });

  it('should return an error if EMAIL or PASSWORD is missing', async () => {
    delete process.env.MY_EMAIL;
    delete process.env.MY_PASSWORD;

    const mockRequest = {
      json: jest.fn().mockResolvedValue({
        email: 'test@example.com',
        name: 'Test User',
        subject: 'Test Subject',
        message: 'Hello! This is a test message.',
      }),
    } as unknown as NextRequest;

    await POST(mockRequest);

    expect(NextResponse.json).toHaveBeenCalledWith({ error: 'E-Mail-Server nicht konfiguriert' }, { status: 500 });
  });

  it('should return an error if request body is invalid', async () => {
    const mockRequest = {
      json: jest.fn().mockResolvedValue({
        email: '',
        name: 'Test User',
        subject: 'Test Subject',
        message: 'Test message',
      }),
    } as unknown as NextRequest;

    await POST(mockRequest);

    expect(NextResponse.json).toHaveBeenCalledWith({ error: 'Alle Felder sind erforderlich' }, { status: 400 });
  });

  it('should return an error if sending email fails', async () => {
    // Mock nodemailer to throw an error
    const originalCreateTransport = require('nodemailer').createTransport;
    require('nodemailer').createTransport = jest.fn().mockReturnValue({
      verify: jest.fn().mockResolvedValue(true),
      sendMail: jest.fn().mockImplementation((options, callback) => {
        callback(new Error('SMTP Error'), null);
      })
    });

    const mockRequest = {
      json: jest.fn().mockResolvedValue({
        email: 'test@example.com',
        name: 'Test User',
        subject: 'Test Subject',
        message: 'Hello! This is a test message.',
      }),
    } as unknown as NextRequest;

    await POST(mockRequest);

    // Check that an error response was called (not specific about the exact error)
    expect(NextResponse.json).toHaveBeenCalledWith(
      expect.objectContaining({ 
        error: expect.any(String)
      }), 
      expect.objectContaining({ status: 500 })
    );

    // Restore original function
    require('nodemailer').createTransport = originalCreateTransport;
  });
});
