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

// We test the API module's structure and endpoint definitions
// The actual HTTP calls are mocked; we verify correct URL/method/payload patterns

vi.mock('axios', () => {
  const mockAxiosInstance = {
    get: vi.fn().mockResolvedValue({ data: {} }),
    post: vi.fn().mockResolvedValue({ data: {} }),
    put: vi.fn().mockResolvedValue({ data: {} }),
    patch: vi.fn().mockResolvedValue({ data: {} }),
    interceptors: {
      request: { use: vi.fn() },
      response: { use: vi.fn() },
    },
  };
  return {
    default: {
      create: vi.fn(() => mockAxiosInstance),
      post: vi.fn(),
    },
  };
});

import { authApi, videoApi, adminApi, profileApi } from '../../src/lib/api';
import api from '../../src/lib/api';

describe('API Client', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('authApi', () => {
    it('should have register method that posts to /auth/register', async () => {
      await authApi.register('user1', 'user1@test.com', 'pass123');
      expect(api.post).toHaveBeenCalledWith(
        '/auth/register',
        { username: 'user1', email: 'user1@test.com', password: 'pass123' }
      );
    });

    it('should have login method that posts to /auth/login', async () => {
      await authApi.login('user1', 'pass123');
      expect(api.post).toHaveBeenCalledWith(
        '/auth/login',
        { username: 'user1', password: 'pass123' }
      );
    });

    it('should have refreshToken method that posts to /auth/token/refresh', async () => {
      await authApi.refreshToken('my-refresh-token');
      expect(api.post).toHaveBeenCalledWith(
        '/auth/token/refresh',
        { refresh: 'my-refresh-token' }
      );
    });

    it('should have getMe method that gets /auth/me', async () => {
      await authApi.getMe();
      expect(api.get).toHaveBeenCalledWith('/auth/me');
    });
  });

  describe('videoApi', () => {
    it('should have generate method that posts FormData to /video/generate', async () => {
      const formData = new FormData();
      formData.append('prompt', 'test prompt');
      await videoApi.generate(formData);
      expect(api.post).toHaveBeenCalledWith(
        '/video/generate',
        formData,
        { headers: { 'Content-Type': 'multipart/form-data' } }
      );
    });
  });

  describe('adminApi', () => {
    it('should have getStats method that gets /admin/stats', async () => {
      await adminApi.getStats();
      expect(api.get).toHaveBeenCalledWith('/admin/stats');
    });

    it('should have getUsers with default params', async () => {
      await adminApi.getUsers();
      expect(api.get).toHaveBeenCalledWith('/admin/users', { params: {} });
    });

    it('should have getUsers with search params', async () => {
      await adminApi.getUsers({ page: 2, search: 'alice' });
      expect(api.get).toHaveBeenCalledWith('/admin/users', {
        params: { page: 2, search: 'alice' },
      });
    });

    it('should have updateUserQuota that puts /admin/users/:id/quota', async () => {
      await adminApi.updateUserQuota(42, 600, 6000);
      expect(api.put).toHaveBeenCalledWith('/admin/users/42/quota', {
        daily_seconds_limit: 600,
        monthly_seconds_limit: 6000,
      });
    });
  });
});

describe('API Client Configuration', () => {
  it('should export authApi with all 4 methods', () => {
    expect(authApi).toBeDefined();
    expect(typeof authApi.register).toBe('function');
    expect(typeof authApi.login).toBe('function');
    expect(typeof authApi.refreshToken).toBe('function');
    expect(typeof authApi.getMe).toBe('function');
  });

  it('should export videoApi with generate method', () => {
    expect(videoApi).toBeDefined();
    expect(typeof videoApi.generate).toBe('function');
  });

  it('should export adminApi with Phase 3 methods', () => {
    expect(adminApi).toBeDefined();
    expect(typeof adminApi.getStats).toBe('function');
    expect(typeof adminApi.getUsers).toBe('function');
    expect(typeof adminApi.getUserDetail).toBe('function');
    expect(typeof adminApi.updateUserQuota).toBe('function');
    expect(typeof adminApi.updateUserStatus).toBe('function');
    expect(typeof adminApi.getRecords).toBe('function');
    expect(typeof adminApi.getSettings).toBe('function');
    expect(typeof adminApi.updateSettings).toBe('function');
  });

  it('should export profileApi with Phase 3 methods', () => {
    expect(profileApi).toBeDefined();
    expect(typeof profileApi.getOverview).toBe('function');
    expect(typeof profileApi.getRecords).toBe('function');
  });
});

describe('Admin API Phase 3 — Additional Endpoint Tests', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('adminApi.getUserDetail fetches /admin/users/:id', async () => {
    await adminApi.getUserDetail(7);
    expect(api.get).toHaveBeenCalledWith('/admin/users/7');
  });

  it('adminApi.updateUserStatus patches /admin/users/:id/status', async () => {
    await adminApi.updateUserStatus(5, false);
    expect(api.patch).toHaveBeenCalledWith('/admin/users/5/status', { is_active: false });
  });

  it('adminApi.getRecords fetches /admin/records with params', async () => {
    await adminApi.getRecords({ page: 2, search: 'bob', start_date: '2026-03-01' });
    expect(api.get).toHaveBeenCalledWith('/admin/records', {
      params: { page: 2, search: 'bob', start_date: '2026-03-01' },
    });
  });

  it('adminApi.getSettings fetches /admin/settings', async () => {
    await adminApi.getSettings();
    expect(api.get).toHaveBeenCalledWith('/admin/settings');
  });

  it('adminApi.updateSettings puts /admin/settings', async () => {
    const settings = {
      default_daily_seconds_limit: 900,
      default_monthly_seconds_limit: 9000,
      announcement: 'test',
      announcement_enabled: true,
    };
    await adminApi.updateSettings(settings);
    expect(api.put).toHaveBeenCalledWith('/admin/settings', settings);
  });
});

describe('Profile API Phase 3', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('profileApi.getOverview fetches /profile/overview with default period', async () => {
    await profileApi.getOverview();
    expect(api.get).toHaveBeenCalledWith('/profile/overview', { params: { period: '7d' } });
  });

  it('profileApi.getOverview supports 30d period', async () => {
    await profileApi.getOverview('30d');
    expect(api.get).toHaveBeenCalledWith('/profile/overview', { params: { period: '30d' } });
  });

  it('profileApi.getRecords fetches /profile/records with pagination', async () => {
    await profileApi.getRecords(2, 10);
    expect(api.get).toHaveBeenCalledWith('/profile/records', {
      params: { page: 2, page_size: 10 },
    });
  });
});
