import { describe, it, expect, vi } from 'vitest';
import { CreateUser } from './CreateUser';
import { IUserRepository } from '../repositories/IUserRepository';
import { User, Email } from '../index';
import { success } from '../shared/Result';

describe('CreateUser Use Case', () => {
  it('should create user successfully', async () => {
    const mockRepository: IUserRepository = {
      save: vi.fn(async (user: User) => success(user)),
      findById: vi.fn(),
      findByEmail: vi.fn(),
      delete: vi.fn(),
    };

    const useCase = new CreateUser(mockRepository);
    const result = await useCase.execute({
      id: 'user-1',
      email: 'test@example.com',
      name: 'John Doe',
    });

    expect(result.isSuccess).toBe(true);
    expect(mockRepository.save).toHaveBeenCalledOnce();
  });

  it('should fail with invalid email', async () => {
    const mockRepository: IUserRepository = {
      save: vi.fn(),
      findById: vi.fn(),
      findByEmail: vi.fn(),
      delete: vi.fn(),
    };

    const useCase = new CreateUser(mockRepository);
    const result = await useCase.execute({
      id: 'user-1',
      email: 'invalid-email',
      name: 'John Doe',
    });

    expect(result.isFailure).toBe(true);
    expect(mockRepository.save).not.toHaveBeenCalled();
  });

  it('should fail with empty name', async () => {
    const mockRepository: IUserRepository = {
      save: vi.fn(),
      findById: vi.fn(),
      findByEmail: vi.fn(),
      delete: vi.fn(),
    };

    const useCase = new CreateUser(mockRepository);
    const result = await useCase.execute({
      id: 'user-1',
      email: 'test@example.com',
      name: '',
    });

    expect(result.isFailure).toBe(true);
    expect(mockRepository.save).not.toHaveBeenCalled();
  });
});
