import { describe, it, expect, vi, beforeEach } from 'vitest';
import { PrismaDuplicateDetector } from '../services/prisma-duplicate-detector';

describe('PrismaDuplicateDetector', () => {
  let detector: PrismaDuplicateDetector;
  let mockPrisma: { $queryRaw: ReturnType<typeof vi.fn> };

  beforeEach(() => {
    mockPrisma = {
      $queryRaw: vi.fn().mockResolvedValue([]),
    };
    detector = new PrismaDuplicateDetector(mockPrisma as any);
  });

  it('should return empty array when no nearby properties found', async () => {
    mockPrisma.$queryRaw.mockResolvedValue([]);

    const result = await detector.findDuplicates({
      excludePropertyId: 'prop-new',
      latitude: 10.7769,
      longitude: 106.7009,
      title: 'Căn hộ đẹp Quận 1',
      propertyType: 'APARTMENT',
    });

    expect(result).toEqual([]);
    expect(mockPrisma.$queryRaw).toHaveBeenCalledTimes(1);
  });

  it('should return duplicates when nearby properties with similar titles exist', async () => {
    mockPrisma.$queryRaw.mockResolvedValue([
      {
        listing_id: 'listing-dup',
        property_id: 'prop-dup',
        title: 'Căn hộ đẹp Quận 1',
        address: '123 Nguyễn Huệ',
        district: 'Quận 1',
        property_type: 'APARTMENT',
        distance_meters: 50,
      },
    ]);

    const result = await detector.findDuplicates({
      excludePropertyId: 'prop-new',
      latitude: 10.7769,
      longitude: 106.7009,
      title: 'Căn hộ đẹp Quận 1',
      propertyType: 'APARTMENT',
    });

    expect(result).toHaveLength(1);
    expect(result[0]!.listingId).toBe('listing-dup');
    expect(result[0]!.propertyId).toBe('prop-dup');
    expect(result[0]!.distanceMeters).toBe(50);
    expect(result[0]!.titleSimilarity).toBe(1); // exact match
  });

  it('should filter out low-similarity results', async () => {
    mockPrisma.$queryRaw.mockResolvedValue([
      {
        listing_id: 'listing-diff',
        property_id: 'prop-diff',
        title: 'Biệt thự sang trọng Thảo Điền',
        address: '456 Quốc Hương',
        district: 'Quận 2',
        property_type: 'APARTMENT',
        distance_meters: 80,
      },
    ]);

    const result = await detector.findDuplicates({
      excludePropertyId: 'prop-new',
      latitude: 10.7769,
      longitude: 106.7009,
      title: 'Căn hộ đẹp Quận 1',
      propertyType: 'APARTMENT',
    });

    // Titles are very different, so similarity should be below threshold
    expect(result).toHaveLength(0);
  });

  it('should use custom radius and similarity threshold', async () => {
    mockPrisma.$queryRaw.mockResolvedValue([]);

    await detector.findDuplicates({
      excludePropertyId: 'prop-new',
      latitude: 10.7769,
      longitude: 106.7009,
      title: 'Test listing',
      propertyType: 'TOWNHOUSE',
      radiusMeters: 200,
      minTitleSimilarity: 0.9,
    });

    expect(mockPrisma.$queryRaw).toHaveBeenCalledTimes(1);
  });
});
