import { describe, it, expect } from 'vitest';
import { GeoFilter } from '../value-objects/geo-filter.vo';

describe('GeoFilter', () => {
  it('creates filter with all properties', () => {
    const filter = GeoFilter.create({
      lat: 10.7769,
      lng: 106.7009,
      radiusKm: 5,
      propertyType: 'APARTMENT',
      transactionType: 'RENT',
      priceMin: 5_000_000,
      priceMax: 20_000_000,
      sortBy: 'price_asc',
      page: 3,
      perPage: 25,
    });

    expect(filter.lat).toBe(10.7769);
    expect(filter.lng).toBe(106.7009);
    expect(filter.radiusKm).toBe(5);
    expect(filter.propertyType).toBe('APARTMENT');
    expect(filter.transactionType).toBe('RENT');
    expect(filter.priceMin).toBe(5_000_000);
    expect(filter.priceMax).toBe(20_000_000);
    expect(filter.sortBy).toBe('price_asc');
    expect(filter.page).toBe(3);
    expect(filter.perPage).toBe(25);
  });

  it('applies default sortBy as distance', () => {
    const filter = GeoFilter.create({ lat: 10.7, lng: 106.7, radiusKm: 5 });
    expect(filter.sortBy).toBe('distance');
  });

  it('applies default page as 1', () => {
    const filter = GeoFilter.create({ lat: 10.7, lng: 106.7, radiusKm: 5 });
    expect(filter.page).toBe(1);
  });

  it('applies default perPage as 20', () => {
    const filter = GeoFilter.create({ lat: 10.7, lng: 106.7, radiusKm: 5 });
    expect(filter.perPage).toBe(20);
  });

  it('caps radiusKm at 100', () => {
    const filter = GeoFilter.create({ lat: 10.7, lng: 106.7, radiusKm: 200 });
    expect(filter.radiusKm).toBe(100);
  });

  it('does not cap radiusKm when under 100', () => {
    const filter = GeoFilter.create({ lat: 10.7, lng: 106.7, radiusKm: 50 });
    expect(filter.radiusKm).toBe(50);
  });

  it('caps perPage at 100', () => {
    const filter = GeoFilter.create({ lat: 10.7, lng: 106.7, radiusKm: 5, perPage: 500 });
    expect(filter.perPage).toBe(100);
  });

  it('returns undefined for unset optional properties', () => {
    const filter = GeoFilter.create({ lat: 10.7, lng: 106.7, radiusKm: 5 });
    expect(filter.propertyType).toBeUndefined();
    expect(filter.transactionType).toBeUndefined();
    expect(filter.priceMin).toBeUndefined();
    expect(filter.priceMax).toBeUndefined();
  });
});
