import { describe, it, expect } from 'vitest';
import { spreadAlertItems } from '@/utils/alertSpread';

describe('spreadAlertItems', () => {
  const makeAlert = (title: string, lat: number, lng: number, cluster_count = 1) => ({
    title,
    coords: [lat, lng],
    cluster_count,
    alert_level: 3,
  });

  it('returns empty array for empty input', () => {
    expect(spreadAlertItems([], 4, new Set())).toEqual([]);
  });

  it('throws on null input (caller must null-check)', () => {
    expect(() => spreadAlertItems(null as any, 4, new Set())).toThrow();
  });

  it('filters out items without coords', () => {
    const items = [
      { title: 'No coords', alert_level: 1 },
      makeAlert('Has coords', 40, -74),
    ];
    const result = spreadAlertItems(items, 4, new Set());
    expect(result.length).toBe(1);
    expect(result[0].title).toBe('Has coords');
  });

  it('filters dismissed alerts by alertKey', () => {
    const items = [
      makeAlert('Fire in NYC', 40.7, -74.0),
      makeAlert('Floods in LA', 34.0, -118.2),
    ];
    const dismissed = new Set(['Fire in NYC|40.7,-74']);
    const result = spreadAlertItems(items, 4, dismissed);
    expect(result.length).toBe(1);
    expect(result[0].title).toBe('Floods in LA');
  });

  it('preserves originalIdx for popup selection', () => {
    const items = [
      { title: 'Skip me', alert_level: 1 }, // no coords
      makeAlert('Alert A', 10, 20),
      makeAlert('Alert B', 30, 40),
    ];
    const result = spreadAlertItems(items, 4, new Set());
    expect(result[0].originalIdx).toBe(1);
    expect(result[1].originalIdx).toBe(2);
  });

  it('adds alertKey and showLine properties', () => {
    const items = [makeAlert('Test Alert', 51.5, -0.1)];
    const result = spreadAlertItems(items, 4, new Set());
    expect(result[0]).toHaveProperty('alertKey');
    expect(result[0]).toHaveProperty('showLine');
    expect(result[0].alertKey).toContain('Test Alert');
  });

  it('spreads overlapping alerts apart (offsets are non-zero for stacked items)', () => {
    // Place 5 alerts at the exact same location — they should be spread apart
    const items = Array.from({ length: 5 }, (_, i) =>
      makeAlert(`Alert ${i}`, 40.0, -74.0)
    );
    const result = spreadAlertItems(items, 8, new Set()); // zoom 8 = close enough to overlap
    const hasNonZeroOffset = result.some(
      (r: any) => Math.abs(r.offsetX) > 1 || Math.abs(r.offsetY) > 1
    );
    expect(hasNonZeroOffset).toBe(true);
  });
});
