import { cleanup, render, screen, waitFor } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';

import JourneyInstructions, { googleMapsUrl } from './JourneyInstructions';

vi.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string, values?: Record<string, string | number>) => {
      if (key === 'areaPane.to') return `To ${values?.destination}`;
      if (key === 'areaPane.journeysFrom') return `Journeys from ${values?.label}`;
      if (key === 'common.min') return 'min';
      if (key === 'common.minute') return 'min';
      if (key === 'common.loading') return 'Loading';
      if (key === 'travel.bestCase') return 'Best case';
      if (key === 'travel.noChange') return 'No change';
      if (key === 'travel.noBuses') return 'No buses';
      if (key === 'areaPane.walk') return 'Walk';
      if (key === 'areaPane.cycle') return 'Cycle';
      if (key === 'areaPane.viewOnGoogleMaps') return 'View on Google Maps';
      if (key === 'areaPane.noJourneyData') return 'No journey data';
      return key;
    },
  }),
}));

describe('JourneyInstructions', () => {
  afterEach(() => {
    cleanup();
    vi.unstubAllGlobals();
    vi.useRealTimers();
  });

  it('keeps the transit leg breakdown visible when best-case time is selected', () => {
    render(
      <JourneyInstructions
        postcode="E14 2DG"
        entries={[]}
        presetJourneys={[
          {
            slug: 'bank',
            label: 'Bank',
            minutes: 42,
            bestMinutes: 25,
            useBest: true,
            noChange: true,
            noBuses: true,
            legs: [
              { mode: 'walk', minutes: 8 },
              {
                mode: 'Jubilee',
                from: 'Canary Wharf (9400ZZLUCAW)',
                to: 'London Bridge (9400ZZLULNB)',
                minutes: 7,
              },
              {
                mode: 'Northern',
                from: 'London Bridge (9400ZZLULNB)',
                to: 'Bank (9400ZZLUBNK)',
                minutes: 3,
              },
            ],
          },
        ]}
        showGoogleMapsLink={false}
      />
    );

    expect(screen.getByText(/Best case/)).toBeTruthy();
    expect(screen.getByText(/No change/)).toBeTruthy();
    expect(screen.getByText(/No buses/)).toBeTruthy();
    expect(screen.getByText('Jubilee line')).toBeTruthy();
    expect(screen.getByText('Northern line')).toBeTruthy();
    expect(screen.getByText(/Canary Wharf/)).toBeTruthy();
  });

  it('builds explicit Google Maps transit directions with destination coordinates', () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date('2026-05-16T12:00:00Z'));

    const url = googleMapsUrl('NW7 2GA', 'Bank tube station', 51.5132819, -0.0895555);
    const parsed = new URL(url);

    expect(parsed.origin + parsed.pathname).toBe('https://www.google.com/maps/dir/');
    expect(parsed.searchParams.get('api')).toBe('1');
    expect(parsed.searchParams.get('origin')).toBe('NW7 2GA');
    expect(parsed.searchParams.get('destination')).toBe('51.5132819,-0.0895555');
    expect(parsed.searchParams.get('travelmode')).toBe('transit');
    expect(parsed.searchParams.get('departure_time')).toBe('1779085800');
  });

  it('does not rewrite destination names when coordinates are unavailable', () => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date('2026-05-16T12:00:00Z'));

    const parsed = new URL(googleMapsUrl('NW7 2GA', 'Bank tube station'));

    expect(parsed.searchParams.get('destination')).toBe('Bank tube station');
  });

  it('requests journey data with the selected transit variant', async () => {
    const fetchMock = vi.fn().mockResolvedValue({
      ok: true,
      json: async () => ({
        journey: null,
        minutes: 42,
        best_minutes: 25,
        destination_lat: 51.5132819,
        destination_lon: -0.0895555,
      }),
    });
    vi.stubGlobal('fetch', fetchMock);

    render(
      <JourneyInstructions
        postcode="E14 2DG"
        entries={[
          {
            mode: 'transit',
            slug: 'bank-tube-station',
            label: 'Bank',
            timeRange: [0, 60],
            useBest: false,
            noChange: true,
            noBuses: true,
          },
        ]}
        showGoogleMapsLink={false}
      />
    );

    await waitFor(() => expect(fetchMock).toHaveBeenCalled());

    const url = fetchMock.mock.calls[0][0] as string;
    const parsed = new URL(url, 'http://localhost');
    expect(parsed.pathname).toBe('/api/journey');
    expect(parsed.searchParams.get('postcode')).toBe('E14 2DG');
    expect(parsed.searchParams.get('mode')).toBe('transit-no-change-no-bus');
    expect(parsed.searchParams.get('slug')).toBe('bank-tube-station');
    await screen.findByText('No change · No buses');
  });
});
