import { describe, it, expect, vi, beforeEach } from 'vitest';
import type { HttpRequestInput } from '../../activities/http-request';

// Mock axios at module level
vi.mock('axios', () => ({
  default: vi.fn(),
}));

import axios from 'axios';
import { httpRequest } from '../../activities/http-request';

const mockedAxios = vi.mocked(axios);

describe('httpRequest activity', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('makes GET request and returns response', async () => {
    mockedAxios.mockResolvedValueOnce({
      status: 200,
      data: { message: 'ok' },
      headers: { 'content-type': 'application/json' },
    } as any);

    const result = await httpRequest({
      url: 'https://api.example.com/data',
      method: 'GET',
    });

    expect(result.status).toBe(200);
    expect(result.data).toEqual({ message: 'ok' });
    expect(mockedAxios).toHaveBeenCalledOnce();
  });

  it('sends body for POST request', async () => {
    mockedAxios.mockResolvedValueOnce({
      status: 201,
      data: { id: 1 },
      headers: {},
    } as any);

    await httpRequest({
      url: 'https://api.example.com/items',
      method: 'POST',
      body: { name: 'test' },
    });

    const callConfig = mockedAxios.mock.calls[0][0] as any;
    expect(callConfig.data).toEqual({ name: 'test' });
    expect(callConfig.method).toBe('post');
  });

  it('applies custom timeout', async () => {
    mockedAxios.mockResolvedValueOnce({
      status: 200,
      data: null,
      headers: {},
    } as any);

    await httpRequest({
      url: 'https://api.example.com',
      method: 'GET',
      timeout: 5000,
    });

    const callConfig = mockedAxios.mock.calls[0][0] as any;
    expect(callConfig.timeout).toBe(5000);
  });

  it('disables redirects when followRedirects is false', async () => {
    mockedAxios.mockResolvedValueOnce({
      status: 302,
      data: null,
      headers: { location: '/new' },
    } as any);

    await httpRequest({
      url: 'https://api.example.com/old',
      method: 'GET',
      followRedirects: false,
    });

    const callConfig = mockedAxios.mock.calls[0][0] as any;
    expect(callConfig.maxRedirects).toBe(0);
  });
});
