import { Test, TestingModule } from '@nestjs/testing';
import { SearchService } from '../search.service';
import { PrismaService } from '../../../prisma/prisma.service';

describe('SearchService', () => {
  let service: SearchService;
  let prisma: PrismaService;

  const mockPrisma = {
    course: { findMany: jest.fn(), count: jest.fn() },
    prompt: { findMany: jest.fn(), count: jest.fn() },
    tool: { findMany: jest.fn(), count: jest.fn() },
    content: { findMany: jest.fn(), count: jest.fn() },
  };

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

    service = module.get<SearchService>(SearchService);
    prisma = module.get<PrismaService>(PrismaService);
    jest.clearAllMocks();
  });

  describe('search', () => {
    it('should return empty results for empty query', async () => {
      const result = await service.search({ q: '' });
      expect(result).toEqual({ results: [], total: 0 });
    });

    it('should search across all types by default', async () => {
      mockPrisma.course.findMany.mockResolvedValue([{ id: 1, title: 'AI课程', _type: 'course' }]);
      mockPrisma.course.count.mockResolvedValue(1);
      mockPrisma.prompt.findMany.mockResolvedValue([]);
      mockPrisma.prompt.count.mockResolvedValue(0);
      mockPrisma.tool.findMany.mockResolvedValue([]);
      mockPrisma.tool.count.mockResolvedValue(0);
      mockPrisma.content.findMany.mockResolvedValue([]);
      mockPrisma.content.count.mockResolvedValue(0);

      const result = await service.search({ q: 'AI' });
      expect(result.results).toHaveLength(1);
      expect(result.results[0]).toHaveProperty('_type', 'course');
      expect(result.total).toBe(1);
    });

    it('should filter by specific type', async () => {
      mockPrisma.tool.findMany.mockResolvedValue([{ id: 1, name: 'ChatGPT', _type: 'tool' }]);
      mockPrisma.tool.count.mockResolvedValue(1);

      const result = await service.search({ q: 'chat', type: 'tools' });
      expect(result.results).toHaveLength(1);
      expect(result.results[0]).toHaveProperty('_type', 'tool');
    });

    it('should respect pagination params', async () => {
      mockPrisma.course.findMany.mockResolvedValue([]);
      mockPrisma.course.count.mockResolvedValue(0);
      mockPrisma.prompt.findMany.mockResolvedValue([]);
      mockPrisma.prompt.count.mockResolvedValue(0);
      mockPrisma.tool.findMany.mockResolvedValue([]);
      mockPrisma.tool.count.mockResolvedValue(0);
      mockPrisma.content.findMany.mockResolvedValue([]);
      mockPrisma.content.count.mockResolvedValue(0);

      const result = await service.search({ q: 'AI', page: 2, pageSize: 5 });
      expect(result.page).toBe(2);
      expect(result.pageSize).toBe(5);
    });

    it('should cap pageSize at 50', async () => {
      mockPrisma.course.findMany.mockResolvedValue([]);
      mockPrisma.course.count.mockResolvedValue(0);
      mockPrisma.prompt.findMany.mockResolvedValue([]);
      mockPrisma.prompt.count.mockResolvedValue(0);
      mockPrisma.tool.findMany.mockResolvedValue([]);
      mockPrisma.tool.count.mockResolvedValue(0);
      mockPrisma.content.findMany.mockResolvedValue([]);
      mockPrisma.content.count.mockResolvedValue(0);

      const result = await service.search({ q: 'AI', pageSize: 100 });
      expect(result.pageSize).toBe(50);
    });
  });
});
