/**
 * anchor-click 测试:钉住 hash 锚点点击的拦截、滚动与 URL 更新。
 * 黑盒驱动:只通过 window.__initAnchorClick 入口 + 真实 DOM 事件派发。
 */
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import './index';

// 模拟 Dioxus 委托监听器:挂在 document 的 bubble 阶段 click，模拟 handleClickNavigate
// 会被触发时的副作用（preventDefault + 整页跳转）。测试用它验证拦截器确实阻止了冒泡。
let dioxusInterceptorCalled = false;

describe('initAnchorClick', () => {
  beforeEach(() => {
    document.body.innerHTML = '';
    history.replaceState(null, '', '#');
    vi.restoreAllMocks();
    dioxusInterceptorCalled = false;
    // 模拟 Dioxus 在 document bubble 阶段的 click 委托监听器。
    // 拦截器在 window capture 阶段 stopPropagation 后，这个监听器不应被触发。
    document.addEventListener(
      'click',
      () => {
        dioxusInterceptorCalled = true;
      },
      false,
    );
    window.__initAnchorClick();
  });
  afterEach(() => {
    document.body.innerHTML = '';
    history.replaceState(null, '', '#');
  });

  it('点击 hash 锚点滚动到目标并阻止 Dioxus 委托监听器', () => {
    const heading = document.createElement('h2');
    heading.id = 'ru-men-zhi-nan';
    document.body.appendChild(heading);

    const anchor = document.createElement('a');
    anchor.setAttribute('href', '#ru-men-zhi-nan');
    document.body.appendChild(anchor);

    const spy = vi.spyOn(window, 'scrollTo').mockImplementation(() => {});
    anchor.click();

    expect(spy).toHaveBeenCalled();
    // 关键:Dioxus 委托监听器未被触发 → handleClickNavigate/browser_open 不会执行。
    expect(dioxusInterceptorCalled).toBe(false);
  });

  it('点击后 URL hash 更新为锚点 id（不触发整页刷新）', () => {
    const heading = document.createElement('h2');
    heading.id = 'section-2';
    document.body.appendChild(heading);

    const anchor = document.createElement('a');
    anchor.setAttribute('href', '#section-2');
    document.body.appendChild(anchor);

    anchor.click();

    expect(window.location.hash).toBe('#section-2');
  });

  it('目标元素不存在时放行，不阻止 Dioxus 原行为', () => {
    const anchor = document.createElement('a');
    anchor.setAttribute('href', '#no-such-heading');
    document.body.appendChild(anchor);

    anchor.click();

    // 目标不存在:拦截器不接管，事件继续冒泡到 Dioxus 监听器。
    expect(dioxusInterceptorCalled).toBe(true);
  });

  it('非 hash 链接不拦截（外链/路径链接交给原行为）', () => {
    const anchor = document.createElement('a');
    anchor.setAttribute('href', '/post/other');
    document.body.appendChild(anchor);

    anchor.click();

    expect(dioxusInterceptorCalled).toBe(true);
  });

  it('带修饰键的点击不拦截（新窗口等交给浏览器）', () => {
    const heading = document.createElement('h2');
    heading.id = 'target';
    document.body.appendChild(heading);

    const anchor = document.createElement('a');
    anchor.setAttribute('href', '#target');
    document.body.appendChild(anchor);

    const spy = vi.spyOn(window, 'scrollTo').mockImplementation(() => {});

    // 模拟 ctrl+click（新标签页）:dispatchEvent 携带 ctrlKey。
    const event = new MouseEvent('click', { bubbles: true, ctrlKey: true });
    anchor.dispatchEvent(event);

    expect(spy).not.toHaveBeenCalled();
    expect(dioxusInterceptorCalled).toBe(true);
  });

  it('重复调用 initAnchorClick 幂等，不会重复注册监听器', () => {
    const heading = document.createElement('h2');
    heading.id = 'dup-target';
    document.body.appendChild(heading);

    const anchor = document.createElement('a');
    anchor.setAttribute('href', '#dup-target');
    document.body.appendChild(anchor);

    // 再次调用（模拟 PostContent 多次挂载）。
    window.__initAnchorClick();
    window.__initAnchorClick();

    const spy = vi.spyOn(window, 'scrollTo').mockImplementation(() => {});
    anchor.click();

    // 即使重复调用，scrollTo 仍只触发一次（监听器只注册一份）。
    expect(spy).toHaveBeenCalledOnce();
  });
});
