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

import { useBrowserPathname } from './use-browser-pathname.js';

function Harness({ link = <a href="/automation">Automation</a> }: { link?: React.ReactNode }) {
  const pathname = useBrowserPathname();
  return (
    <>
      {link}
      <main id="main-content" tabIndex={-1}>
        {pathname}
      </main>
    </>
  );
}

afterEach(() => {
  cleanup();
  window.history.replaceState(null, '', '/');
  vi.restoreAllMocks();
});

describe('useBrowserPathname', () => {
  it('pushes eligible same-origin links and updates pathname without reloading', () => {
    window.history.replaceState(null, '', '/fleet');
    const pushState = vi.spyOn(window.history, 'pushState');
    const scrollTo = vi.spyOn(window, 'scrollTo').mockImplementation(() => undefined);
    render(<Harness />);

    const link = screen.getByRole('link', { name: 'Automation' });
    const accepted = fireEvent.click(link);

    expect(accepted).toBe(false);
    expect(pushState).toHaveBeenCalledWith(null, '', '/automation');
    expect(screen.getByRole('main').textContent).toBe('/automation');
    expect(document.activeElement).toBe(screen.getByRole('main'));
    expect(scrollTo).toHaveBeenCalledWith({ top: 0, left: 0, behavior: 'auto' });
  });

  it('tracks browser history traversal and restores the page start', () => {
    window.history.replaceState(null, '', '/automation');
    const scrollTo = vi.spyOn(window, 'scrollTo').mockImplementation(() => undefined);
    render(<Harness />);

    window.history.replaceState(null, '', '/fleet');
    fireEvent(window, new PopStateEvent('popstate'));

    expect(screen.getByRole('main').textContent).toBe('/fleet');
    expect(document.activeElement).toBe(screen.getByRole('main'));
    expect(scrollTo).toHaveBeenCalledWith({ top: 0, left: 0, behavior: 'auto' });
  });

  it.each([
    [
      'target window',
      <a href="/automation" target="_blank">
        Excluded
      </a>,
      {},
    ],
    [
      'download',
      <a href="/automation" download>
        Excluded
      </a>,
      {},
    ],
    ['external origin', <a href="https://example.com/automation">Excluded</a>, {}],
    ['hash-only navigation', <a href="/fleet#cards">Excluded</a>, {}],
    ['middle click', <a href="/automation">Excluded</a>, { button: 1 }],
    ['meta click', <a href="/automation">Excluded</a>, { metaKey: true }],
    ['control click', <a href="/automation">Excluded</a>, { ctrlKey: true }],
    ['shift click', <a href="/automation">Excluded</a>, { shiftKey: true }],
    ['alt click', <a href="/automation">Excluded</a>, { altKey: true }],
  ])('leaves %s to the browser', (_label, link, eventInit) => {
    window.history.replaceState(null, '', '/fleet');
    const pushState = vi.spyOn(window.history, 'pushState');
    render(<Harness link={link} />);

    let hookPrevented = true;
    const suppressBrowserNavigation = (event: MouseEvent) => {
      hookPrevented = event.defaultPrevented;
      event.preventDefault();
    };
    document.addEventListener('click', suppressBrowserNavigation, { once: true });
    const event = new MouseEvent('click', { bubbles: true, cancelable: true, ...eventInit });
    screen.getByRole('link', { name: 'Excluded' }).dispatchEvent(event);

    expect(hookPrevented).toBe(false);
    expect(pushState).not.toHaveBeenCalled();
    expect(screen.getByRole('main').textContent).toBe('/fleet');
  });
});
