import { describe, it, expect, beforeEach, vi } from 'vitest';
import fs from 'fs-extra';
import path from 'path';
import { logger } from '../../src/utils/logger';
import { createHttpClient } from '../../src/commands/http-client';
import * as templates from '../../src/templates/http-client';

vi.mock('fs-extra');
vi.mock('../../src/utils/logger', () => ({
  logger: {
    error: vi.fn(),
    success: vi.fn(),
    info: vi.fn(),
    warning: vi.fn(),
    log: vi.fn(),
  }
}));
vi.mock('../../src/templates/http-client', () => ({
  getHttpClientTemplate: vi.fn(),
}));

describe('createHttpClient', () => {
  const targetPath = path.join(process.cwd(), 'src', 'lib', 'http-client.ts');
  const targetDir = path.dirname(targetPath);

  beforeEach(() => {
    vi.clearAllMocks();
    (templates.getHttpClientTemplate as any).mockReturnValue('// http client');
  });

  it('should create the http client file if it does not exist', async () => {
    (fs.exists as any).mockResolvedValue(false);
    (fs.ensureDir as any).mockResolvedValue(undefined);
    (fs.writeFile as any).mockResolvedValue(undefined);

    await createHttpClient();

    expect(fs.exists).toHaveBeenCalledWith(targetPath);
    expect(fs.ensureDir).toHaveBeenCalledWith(targetDir);
    expect(fs.writeFile).toHaveBeenCalledWith(targetPath, '// http client', 'utf8');
    expect(logger.success).toHaveBeenCalledWith('HTTP client generated successfully!');
    expect(logger.info).toHaveBeenCalledWith('Location: ' + targetPath);
    expect(logger.info).toHaveBeenCalledWith("💡 You can now import it with: import { httpClient } from './lib/http-client'");
  });

  it('should not overwrite if http client already exists', async () => {
    (fs.exists as any).mockResolvedValue(true);

    await createHttpClient();

    expect(fs.exists).toHaveBeenCalledWith(targetPath);
    expect(logger.error).toHaveBeenCalledWith('HTTP client already exists at ' + targetPath);
    expect(fs.ensureDir).not.toHaveBeenCalled();
    expect(fs.writeFile).not.toHaveBeenCalled();
  });

  it('should handle errors during file creation', async () => {
    (fs.exists as any).mockResolvedValue(false);
    (fs.ensureDir as any).mockResolvedValue(undefined);
    const error = new Error('Write failed');
    (fs.writeFile as any).mockRejectedValue(error);

    await createHttpClient();

    expect(logger.error).toHaveBeenCalledWith('Error creating HTTP client: Write failed');
  });
}); 