import { describe, it, expect, vi, beforeEach } from 'vitest';

// Deterministic base URL
vi.mock('@/lib/config', () => ({ getWebhookUrl: () => 'https://api.test' }));

// apiFetch mock
const apiFetchMock = vi.fn();
vi.mock('@/utils/apiFetch', () => ({
  apiFetch: (...args: any[]) => apiFetchMock(...args),
}));

import { fetchEvents, fetchCurrentEvents, createEventFromUrl } from '@/features/event/api/eventService';

function okJson(data: any) {
  return new Response(JSON.stringify(data), {
    status: 200,
    headers: { 'Content-Type': 'application/json' },
  });
}
function status(code: number) {
  return new Response('', { status: code });
}

beforeEach(() => {
  apiFetchMock.mockReset();
});

describe('eventService API', () => {
  it('fetchEvents returns array data', async () => {
    apiFetchMock.mockResolvedValueOnce(okJson([{ id: 'e1' }, { id: 'e2' }]));

    const list = await fetchEvents(async (...args: any[]) => apiFetchMock(...args));

    expect(apiFetchMock).toHaveBeenCalledWith('https://api.test/events', {
      method: 'GET',
      headers: { 'Content-Type': 'application/json' },
    });
    expect(Array.isArray(list)).toBe(true);
    expect(list).toHaveLength(2);
  });

  it('fetchCurrentEvents returns normalized array when API returns single object', async () => {
    apiFetchMock.mockResolvedValueOnce(okJson({ id: 'single' }));

    const list = await fetchCurrentEvents(async (...args: any[]) => apiFetchMock(...args));

    expect(apiFetchMock).toHaveBeenCalledWith('https://api.test/events/get_current', {
      method: 'GET',
      headers: { 'Content-Type': 'application/json' },
    });
    expect(Array.isArray(list)).toBe(true);
    expect(list).toHaveLength(1);
    expect(list[0]).toMatchObject({ id: 'single' });
  });

  it('createEventFromUrl posts URL and returns parsed data.message_from_ai when present', async () => {
    apiFetchMock.mockResolvedValueOnce(okJson({ message_from_ai: { name: 'AI Event' } }));

    const result = await createEventFromUrl('https://example.com');

    const [url, init] = apiFetchMock.mock.calls[0] as [string, RequestInit];
    expect(url).toBe('https://api.test/event/new_fromurl');
    expect((init?.headers as any)['Content-Type']).toBe('application/json');
    expect(JSON.parse(String(init?.body))).toMatchObject({ url: 'https://example.com', command: 'eventmodus_extract_from_url' });
    expect(result).toEqual({ name: 'AI Event' });
  });

  it('fetchEvents throws on non-ok response', async () => {
    apiFetchMock.mockResolvedValueOnce(status(500));
    await expect(fetchEvents(async (...args: any[]) => apiFetchMock(...args))).rejects.toThrow();
  });
});
