import { describe, it, expect, beforeEach, vi } from 'vitest';
import path from 'path';
import { deleteDomain } from '../../src/commands/delete';
import type { FileSystem } from '../../src/utils/file-operations';
import type { Logger } from '../../src/utils/logging';
import * as paths from '../../src/utils/paths';
import { validateFileExists, removeFile } from '../../src/utils/file-operations';

vi.mock('../../src/utils/paths', () => ({
  buildDomainDirectoryPath: vi.fn(),
}));
vi.mock('../../src/utils/file-operations', () => ({
  validateFileExists: vi.fn(),
  removeFile: vi.fn(),
}));

const domainName = 'test-domain';
const domainPath = path.join(process.cwd(), 'src', 'domains', domainName);

// Mocks
const mockFileSystem: FileSystem = {
  exists: vi.fn(),
  pathExists: vi.fn(),
  ensureDir: vi.fn() as unknown as FileSystem['ensureDir'],
  writeFile: vi.fn() as unknown as FileSystem['writeFile'],
  readFile: vi.fn() as unknown as FileSystem['readFile'],
  readdir: vi.fn() as unknown as FileSystem['readdir'],
  stat: vi.fn() as unknown as FileSystem['stat'],
  mkdir: vi.fn() as unknown as FileSystem['mkdir'],
  remove: vi.fn(),
};

const mockLogger: Logger = {
  error: vi.fn(),
  success: vi.fn(),
  info: vi.fn(),
  warning: vi.fn(),
  log: vi.fn(),
};

describe('deleteDomain', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    (paths.buildDomainDirectoryPath as any).mockReturnValue(domainPath);
  });

  it('should delete an existing domain', async () => {
    (validateFileExists as any).mockResolvedValue(true);
    (removeFile as any).mockResolvedValue(undefined);

    await deleteDomain(domainName, false, mockFileSystem, mockLogger);

    expect(paths.buildDomainDirectoryPath).toHaveBeenCalledWith(domainName);
    expect(validateFileExists).toHaveBeenCalledWith(mockFileSystem, domainPath);
    expect(removeFile).toHaveBeenCalledWith(mockFileSystem, domainPath);
    expect(mockLogger.success).toHaveBeenCalledWith(`Domain "${domainName}" deleted successfully!`);
  });

  it('should handle non-existent domain', async () => {
    (validateFileExists as any).mockResolvedValue(false);

    await deleteDomain(domainName, false, mockFileSystem, mockLogger);

    expect(paths.buildDomainDirectoryPath).toHaveBeenCalledWith(domainName);
    expect(validateFileExists).toHaveBeenCalledWith(mockFileSystem, domainPath);
    expect(removeFile).not.toHaveBeenCalled();
    expect(mockLogger.error).toHaveBeenCalledWith(`Domain "${domainName}" not found at ${domainPath}`);
  });

  it('should handle errors during deletion', async () => {
    (validateFileExists as any).mockResolvedValue(true);
    (removeFile as any).mockRejectedValue(new Error('fail'));

    await deleteDomain(domainName, false, mockFileSystem, mockLogger);

    expect(paths.buildDomainDirectoryPath).toHaveBeenCalledWith(domainName);
    expect(mockLogger.error).toHaveBeenCalledWith(`Error deleting domain "${domainName}": fail`);
  });
}); 