import { beforeEach, describe, expect, it, vi } from 'vitest';
import { getCurrentUser, refreshSession, signIn, signOut } from '@/shared/api/auth';
import { apiRequest } from '@/shared/api/httpClient';
import type { CurrentUser, SignInRequest } from '@/shared/types/auth';

vi.mock('@/shared/api/httpClient', () => ({
  apiRequest: vi.fn(),
}));

const apiRequestMock = vi.mocked(apiRequest);

describe('auth API', () => {
  beforeEach(() => {
    apiRequestMock.mockReset();
  });

  it('signs in through the local auth endpoint and returns the current user profile', async () => {
    const currentUser: CurrentUser = {
      id: 'user-1',
      email: 'teacher@example.com',
      firstName: 'Teacher',
      lastName: 'One',
      app_role: { name: 'teacher' },
    };
    apiRequestMock.mockResolvedValueOnce(currentUser);
    const request: SignInRequest = {
      email: 'teacher@example.com',
      password: 'password-1',
    };

    await expect(signIn(request)).resolves.toEqual(currentUser);

    expect(apiRequestMock).toHaveBeenCalledWith('/auth/signin/local', {
      method: 'POST',
      body: {
        email: 'teacher@example.com',
        password: 'password-1',
      },
    });
  });

  it('loads the current user through the auth profile endpoint', async () => {
    const currentUser: CurrentUser = {
      id: 'user-1',
      email: 'teacher@example.com',
      firstName: 'Teacher',
      lastName: 'One',
      app_role: { name: 'teacher' },
    };
    apiRequestMock.mockResolvedValueOnce(currentUser);

    await expect(getCurrentUser()).resolves.toEqual(currentUser);

    expect(apiRequestMock).toHaveBeenCalledWith('/auth/me');
  });

  it('signs out through the backend session endpoint', async () => {
    apiRequestMock.mockResolvedValueOnce(undefined);

    await expect(signOut()).resolves.toBeUndefined();

    expect(apiRequestMock).toHaveBeenCalledWith('/auth/signout', {
      method: 'POST',
    });
  });

  it('refreshes the backend session without exposing tokens', async () => {
    const currentUser: CurrentUser = {
      id: 'user-1',
      email: 'teacher@example.com',
      firstName: 'Teacher',
      lastName: 'One',
      app_role: { name: 'teacher' },
    };
    apiRequestMock.mockResolvedValueOnce(currentUser);

    await expect(refreshSession()).resolves.toEqual(currentUser);

    expect(apiRequestMock).toHaveBeenCalledWith('/auth/refresh', {
      method: 'POST',
      skipAuthRefresh: true,
    });
  });
});
