/**
 * PairView 單元測試（Fix-F2 / Fix-F3 涵蓋）
 *
 * 驗證重點：
 *   1. Fix-F2：Esc 鍵 dispatch agent:switch-tab → status
 *   2. Fix-F2：submitting=true 時 Esc 不觸發
 *   3. Fix-F2：unmount 後不再響應 keydown（避免 memory leak / 跨 view 殘留）
 *   4. Fix-F3：點擊「前往雲端」改用 agentAPI.openURL（不直接呼叫 window.open）
 *
 * 不測試：
 *   - usePair 的 submitting / lastError 行為（hook 自己有測試）
 *   - TokenInput 內部驗證（token-input.test.tsx 負責）
 */

import { act, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import { LocaleProvider } from "@/lib/i18n/context";

// usePair 用 ref 控制：每個 test 改 currentSubmitting 即可影響 hook 回傳
let currentSubmitting = false;
const pairFn = vi.fn().mockResolvedValue(undefined);
const resetFn = vi.fn();

vi.mock("@/hooks/use-pair", () => ({
  usePair: () => ({
    pair: pairFn,
    submitting: currentSubmitting,
    lastError: null,
    reset: resetFn,
  }),
}));

const openURLMock = vi.fn();
vi.mock("@/lib/agent-api", () => ({
  agentAPI: {
    openURL: (url: string) => openURLMock(url),
  },
}));

import { AGENT_SWITCH_TAB_EVENT } from "./status-view";
import { PairView } from "./pair-view";

function renderPair() {
  return render(
    <LocaleProvider>
      <PairView />
    </LocaleProvider>,
  );
}

describe("<PairView /> — Esc 取消（Fix-F2）", () => {
  let dispatchSpy: ReturnType<typeof vi.spyOn>;

  beforeEach(() => {
    currentSubmitting = false;
    pairFn.mockClear();
    resetFn.mockClear();
    openURLMock.mockClear();
    dispatchSpy = vi.spyOn(window, "dispatchEvent");
  });

  afterEach(() => {
    dispatchSpy.mockRestore();
  });

  it("按 Esc 會 dispatch agent:switch-tab → status", () => {
    renderPair();
    act(() => {
      window.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape" }));
    });

    const switchCall = dispatchSpy.mock.calls.find(([ev]) => {
      return ev instanceof CustomEvent && ev.type === AGENT_SWITCH_TAB_EVENT;
    });
    expect(switchCall).toBeDefined();
    const [event] = switchCall as [CustomEvent<{ value: string }>];
    expect(event.detail.value).toBe("status");
  });

  it("submitting=true 時按 Esc 不 dispatch（避免打斷送出）", () => {
    currentSubmitting = true;
    renderPair();

    act(() => {
      window.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape" }));
    });

    const switchCall = dispatchSpy.mock.calls.find(([ev]) => {
      return ev instanceof CustomEvent && ev.type === AGENT_SWITCH_TAB_EVENT;
    });
    expect(switchCall).toBeUndefined();
  });

  it("unmount 後 Esc 不再響應（解綁 listener）", () => {
    const { unmount } = renderPair();
    unmount();

    dispatchSpy.mockClear();
    act(() => {
      window.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape" }));
    });

    const switchCall = dispatchSpy.mock.calls.find(([ev]) => {
      return ev instanceof CustomEvent && ev.type === AGENT_SWITCH_TAB_EVENT;
    });
    expect(switchCall).toBeUndefined();
  });

  it("非 Escape 鍵不觸發切 tab", () => {
    renderPair();
    act(() => {
      window.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter" }));
      window.dispatchEvent(new KeyboardEvent("keydown", { key: "Tab" }));
    });

    const switchCall = dispatchSpy.mock.calls.find(([ev]) => {
      return ev instanceof CustomEvent && ev.type === AGENT_SWITCH_TAB_EVENT;
    });
    expect(switchCall).toBeUndefined();
  });
});

describe("<PairView /> — 雲端連結改用 agentAPI.openURL（Fix-F3）", () => {
  beforeEach(() => {
    currentSubmitting = false;
    openURLMock.mockClear();
  });

  it("點擊「前往雲端」連結會呼叫 agentAPI.openURL", () => {
    renderPair();

    fireEvent.click(screen.getByTestId("pair-link-cloud"));

    expect(openURLMock).toHaveBeenCalledOnce();
    expect(openURLMock).toHaveBeenCalledWith(
      expect.stringMatching(/^https:\/\/visionA\.cloud\/devices\/pair$/i),
    );
  });
});
