import { UsersController } from './users.controller';
import type { AuthenticatedUser } from '../../../../libs/auth/src';

describe('UsersController', () => {
  const currentUser: AuthenticatedUser = {
    id: 'u1',
    externalSubjectId: 'sub-1',
    displayName: 'Alex',
    email: 'a@example.com',
  };

  it('GET /users/me returns the current user profile', async () => {
    const usersService = {
      findById: jest.fn().mockResolvedValue({
        id: 'u1',
        externalSubjectId: 'sub-1',
        displayName: 'Alex',
        email: 'a@example.com',
        createdAt: new Date('2026-01-01'),
        updatedAt: new Date('2026-01-02'),
      }),
    };
    const preferencesService = { getOrDefault: jest.fn(), upsert: jest.fn() };
    const controller = new UsersController(
      usersService as never,
      preferencesService as never,
    );

    const result = await controller.me(currentUser);

    expect(usersService.findById).toHaveBeenCalledWith('u1');
    expect(result).toEqual({
      id: 'u1',
      displayName: 'Alex',
      email: 'a@example.com',
      createdAt: new Date('2026-01-01'),
      updatedAt: new Date('2026-01-02'),
    });
  });

  it('GET /users/me/preferences returns the effective preference', async () => {
    const preference = {
      userId: 'u1',
      preferredPace: null,
      preferredBudgetLevel: null,
      maxWalkingDistanceKm: null,
      preferredStartTime: null,
      childFriendlyPreferred: false,
      interests: [],
      notes: null,
    };
    const usersService = { findById: jest.fn() };
    const preferencesService = {
      getOrDefault: jest.fn().mockResolvedValue(preference),
      upsert: jest.fn(),
    };
    const controller = new UsersController(
      usersService as never,
      preferencesService as never,
    );

    await expect(controller.getPreferences(currentUser)).resolves.toEqual(
      preference,
    );
    expect(preferencesService.getOrDefault).toHaveBeenCalledWith('u1');
  });

  it('PUT /users/me/preferences round-trips the dto through the service', async () => {
    const dto = { childFriendlyPreferred: true };
    const updated = {
      userId: 'u1',
      preferredPace: null,
      preferredBudgetLevel: null,
      maxWalkingDistanceKm: null,
      preferredStartTime: null,
      childFriendlyPreferred: true,
      interests: [],
      notes: null,
    };
    const usersService = { findById: jest.fn() };
    const preferencesService = {
      getOrDefault: jest.fn(),
      upsert: jest.fn().mockResolvedValue(updated),
    };
    const controller = new UsersController(
      usersService as never,
      preferencesService as never,
    );

    await expect(
      controller.updatePreferences(currentUser, dto),
    ).resolves.toEqual(updated);
    expect(preferencesService.upsert).toHaveBeenCalledWith('u1', dto);
  });
});
