import { Test, TestingModule } from '@nestjs/testing';
import { SearchSuggestionService } from '@/modules/knowledge-base/services/search-suggestion.service';
import { PrismaService } from '@/core/database/prisma/prisma.service';

describe('SearchSuggestionService', () => {
  let service: SearchSuggestionService;

  const mockPrismaService: {
    searchLog: { findMany: jest.Mock; deleteMany: jest.Mock };
    knowledgeArticle: { findMany: jest.Mock };
    sPDocumentIndex: { findMany: jest.Mock };
    $queryRaw: jest.Mock;
  } = {
    searchLog: {
      findMany: jest.fn(),
      deleteMany: jest.fn(),
    },
    knowledgeArticle: {
      findMany: jest.fn(),
    },
    sPDocumentIndex: {
      findMany: jest.fn(),
    },
    $queryRaw: jest.fn(),
  };

  beforeEach(async () => {
    const testingModule: TestingModule = await Test.createTestingModule({
      providers: [
        SearchSuggestionService,
        {
          provide: PrismaService,
          useValue: mockPrismaService,
        },
      ],
    }).compile();

    service = testingModule.get<SearchSuggestionService>(
      SearchSuggestionService,
    );
    jest.clearAllMocks();
  });

  it('输入长度小于 2 时应返回空结果且不查询数据库', async () => {
    const result = await service.suggest('user-1', 'a', 8);

    expect(result).toEqual([]);
    expect(mockPrismaService.searchLog.findMany).not.toHaveBeenCalled();
    expect(mockPrismaService.$queryRaw).not.toHaveBeenCalled();
    expect(mockPrismaService.knowledgeArticle.findMany).not.toHaveBeenCalled();
    expect(mockPrismaService.sPDocumentIndex.findMany).not.toHaveBeenCalled();
  });

  it('应按标题 -> 最近搜索 -> 热门搜索的顺序合并并去重', async () => {
    mockPrismaService.searchLog.findMany.mockResolvedValue([
      { query: '请假流程' },
      { query: '请假审批' },
    ]);
    mockPrismaService.$queryRaw.mockResolvedValue([
      { query: '请假审批', count: BigInt(12) },
      { query: '请假制度', count: BigInt(8) },
    ]);
    mockPrismaService.knowledgeArticle.findMany.mockResolvedValue([
      { title: '请假申请操作手册' },
      { title: '请假流程' },
    ]);
    mockPrismaService.sPDocumentIndex.findMany.mockResolvedValue([
      { title: '请假政策 FAQ' },
    ]);

    const result = await service.suggest('user-1', '请假', 8);

    expect(result).toEqual([
      { text: '请假申请操作手册', source: 'TITLE' },
      { text: '请假政策 FAQ', source: 'TITLE' },
      { text: '请假流程', source: 'RECENT_SEARCH' },
      { text: '请假审批', source: 'RECENT_SEARCH' },
      { text: '请假制度', source: 'TOP_QUERY' },
    ]);
    expect(mockPrismaService.searchLog.findMany).toHaveBeenCalledTimes(1);
    expect(mockPrismaService.$queryRaw).toHaveBeenCalledTimes(1);
    expect(mockPrismaService.knowledgeArticle.findMany).toHaveBeenCalledTimes(
      1,
    );
    expect(mockPrismaService.sPDocumentIndex.findMany).toHaveBeenCalledTimes(1);
  });

  it('删除单条最近搜索应只删除当前用户对应关键词', async () => {
    mockPrismaService.searchLog.deleteMany.mockResolvedValue({ count: 1 });

    const deleted = await service.removeRecentSearch('user-1', '请假流程');

    expect(deleted).toBe(1);
    expect(mockPrismaService.searchLog.deleteMany).toHaveBeenCalledTimes(1);
  });

  it('清空最近搜索应删除当前用户全部搜索记录', async () => {
    mockPrismaService.searchLog.deleteMany.mockResolvedValue({ count: 3 });

    const deleted = await service.clearRecentSearches('user-1');

    expect(deleted).toBe(3);
    expect(mockPrismaService.searchLog.deleteMany).toHaveBeenCalledTimes(1);
  });
});
