import { KnowledgeBaseService } from './knowledge-base.service';

describe('KnowledgeBaseService.remove', () => {
  const repository = {
    countByUserId: jest.fn(),
    create: jest.fn(),
    findAllByUserId: jest.fn(),
    findById: jest.fn(),
    update: jest.fn(),
    softDelete: jest.fn(),
    togglePin: jest.fn(),
    setVisibility: jest.fn(),
    subscribe: jest.fn(),
    unsubscribe: jest.fn(),
    findSubscribed: jest.fn(),
    findAllPublic: jest.fn(),
  };

  const prisma = {
    knowledgeFolder: {
      findUnique: jest.fn(),
      create: jest.fn(),
      findMany: jest.fn(),
      update: jest.fn(),
      updateMany: jest.fn(),
    },
    knowledgeItem: {
      create: jest.fn(),
      updateMany: jest.fn(),
    },
  };

  const storage = {
    getDownloadUrl: jest.fn(),
  };

  const sourceRepository = {
    findFileSourcesByKnowledgeBase: jest.fn(),
    softDeleteMany: jest.fn(),
  };

  const filesService = {
    deleteFile: jest.fn(),
  };

  const safety = {
    check: jest.fn(),
  };

  let service: KnowledgeBaseService;

  beforeEach(() => {
    jest.clearAllMocks();
    repository.softDelete.mockResolvedValue(true);
    sourceRepository.softDeleteMany.mockResolvedValue({ count: 2 });
    filesService.deleteFile.mockResolvedValue({ success: true });

    service = new KnowledgeBaseService(
      repository as never,
      prisma as never,
      storage as never,
      sourceRepository as never,
      filesService as never,
      safety as never,
    );
  });

  it('deletes linked files and soft deletes file sources before deleting knowledge base', async () => {
    repository.findById.mockResolvedValue({
      id: 'kb-1',
      userId: 'u1',
    });
    sourceRepository.findFileSourcesByKnowledgeBase.mockResolvedValue([
      { id: 'source-1', fileId: 'file-1' },
      { id: 'source-2', fileId: 'file-2' },
    ]);

    await service.remove('u1', 'kb-1');

    expect(filesService.deleteFile).toHaveBeenNthCalledWith(1, 'u1', 'file-1');
    expect(filesService.deleteFile).toHaveBeenNthCalledWith(2, 'u1', 'file-2');
    expect(sourceRepository.softDeleteMany).toHaveBeenCalledWith(['source-1', 'source-2']);
    expect(repository.softDelete).toHaveBeenCalledWith('kb-1');
  });

  it('still deletes knowledge base when there are no linked file sources', async () => {
    repository.findById.mockResolvedValue({
      id: 'kb-1',
      userId: 'u1',
    });
    sourceRepository.findFileSourcesByKnowledgeBase.mockResolvedValue([]);

    await service.remove('u1', 'kb-1');

    expect(filesService.deleteFile).not.toHaveBeenCalled();
    expect(sourceRepository.softDeleteMany).toHaveBeenCalledWith([]);
    expect(repository.softDelete).toHaveBeenCalledWith('kb-1');
  });
});
