import { describe, expect, it } from 'vitest';

import type { POI } from '../types';
import {
  formatStationDistance,
  selectNearbyStations,
  stationSearchBounds,
} from './nearby-stations';

function poi(name: string, lat: number, lng: number): POI {
  return {
    id: name,
    name,
    category: 'Rail station',
    icon_category: 'Rail station',
    group: 'Public Transport',
    lat,
    lng,
    emoji: '',
  };
}

describe('selectNearbyStations', () => {
  const origin = { lat: 51.5, lon: -0.1 };

  it('returns every station within 1km when any station is inside 1km', () => {
    const stations = selectNearbyStations(
      [poi('Close A', 51.501, -0.1), poi('Close B', 51.502, -0.1), poi('Fallback', 51.511, -0.1)],
      origin
    );

    expect(stations.map((station) => station.name)).toEqual(['Close A', 'Close B']);
  });

  it('falls back to the nearest three stations within 2km when none are inside 1km', () => {
    const stations = selectNearbyStations(
      [
        poi('Fourth', 51.516, -0.1),
        poi('First', 51.51, -0.1),
        poi('Outside', 51.53, -0.1),
        poi('Third', 51.514, -0.1),
        poi('Second', 51.512, -0.1),
      ],
      origin
    );

    expect(stations.map((station) => station.name)).toEqual(['First', 'Second', 'Third']);
  });

  it('formats sub-kilometre and kilometre distances', () => {
    expect(formatStationDistance(0.234)).toBe('234m');
    expect(formatStationDistance(1.234)).toBe('1.2km');
  });
});

describe('stationSearchBounds', () => {
  it('builds a box around the origin', () => {
    const bounds = stationSearchBounds({ lat: 51.5, lon: -0.1 });

    expect(bounds.south).toBeLessThan(51.5);
    expect(bounds.north).toBeGreaterThan(51.5);
    expect(bounds.west).toBeLessThan(-0.1);
    expect(bounds.east).toBeGreaterThan(-0.1);
  });
});
