/* @vitest-environment jsdom */

import { type RefObject } from "react";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import {
  installChatKeyboardDiagnostics,
  isChatKeyboardDiagnosticsEnabled,
} from "../use-chat-keyboard-diagnostics";

vi.mock("@/utils/browser-detect", () => ({
  BrowserDetector: {
    getBrowserInfo: vi.fn(() => ({
      name: "Chrome WebView",
      version: "126.0.0.0",
      inAppBrowserName: "facebook",
    })),
  },
}));

vi.mock("@/utils/platform-detect", () => ({
  PlatformDetector: {
    getPlatformInfo: vi.fn(() => ({
      platform: "android",
      osName: "Android",
      osVersion: "15",
      deviceVendor: "OnePlus",
      deviceModel: "PLB110",
    })),
  },
}));

class MockVisualViewport extends EventTarget {
  height = 460;
  offsetLeft = 0;
  offsetTop = 0;
  scale = 1;
  width = 390;
}

class MockVirtualKeyboard extends EventTarget {
  overlaysContent = false;
  boundingRect = {
    x: 0,
    y: 460,
    width: 390,
    height: 300,
  };
}

describe("chat keyboard diagnostics", () => {
  let consoleInfo: ReturnType<typeof vi.spyOn>;
  let visualViewport: MockVisualViewport;
  let virtualKeyboard: MockVirtualKeyboard;

  beforeEach(() => {
    visualViewport = new MockVisualViewport();
    virtualKeyboard = new MockVirtualKeyboard();
    Object.defineProperty(window, "visualViewport", {
      configurable: true,
      value: visualViewport,
    });
    Object.defineProperty(navigator, "virtualKeyboard", {
      configurable: true,
      value: virtualKeyboard,
    });
    consoleInfo = vi.spyOn(window.console, "info").mockImplementation(() => {});
  });

  afterEach(() => {
    window.__keyboardDebugCleanup?.();
    document.documentElement.style.removeProperty("--app-viewport-height");
    document.documentElement.style.removeProperty("--app-visible-height");
    vi.restoreAllMocks();
  });

  it("enables diagnostics only for the explicit query parameter", () => {
    expect(isChatKeyboardDiagnosticsEnabled("?keyboard_debug=1")).toBe(true);
    expect(isChatKeyboardDiagnosticsEnabled("?keyboard_debug=0")).toBe(false);
    expect(isChatKeyboardDiagnosticsEnabled("")).toBe(false);
  });

  it("records viewport events and exposes manual snapshot helpers", () => {
    const input = document.createElement("textarea");
    document.documentElement.style.setProperty("--app-viewport-height", "800px");
    document.documentElement.style.setProperty("--app-visible-height", "460px");
    input.style.setProperty("--chat-keyboard-bottom-inset", "300px");
    document.body.append(input);
    input.focus();
    const inputRef = { current: input } as RefObject<HTMLElement | null>;

    const cleanup = installChatKeyboardDiagnostics(inputRef);

    expect(window.__keyboardDebugSnapshot).toBeTypeOf("function");
    expect(window.__keyboardDebugCleanup).toBe(cleanup);
    expect(window.__keyboardDebugSnapshot?.()).toMatchObject({
      event: "manual",
      visualViewportSupported: true,
      visualHeight: 460,
      virtualKeyboardSupported: true,
      virtualKeyboardOverlaysContent: false,
      virtualKeyboardRect: { height: 300 },
      activeElement: "TEXTAREA",
      activeFocused: true,
      inputBarTop: 0,
      inputBarBottom: 0,
      keyboardBottomInset: "300px",
      appViewportHeight: "800px",
      appVisibleHeight: "460px",
      platform: { name: "android", deviceModel: "PLB110" },
      browser: { inAppBrowserName: "facebook" },
    });

    visualViewport.dispatchEvent(new Event("resize"));
    expect(consoleInfo).toHaveBeenLastCalledWith(
      "[keyboard-debug]",
      expect.objectContaining({ event: "visualViewport.resize" }),
    );

    const callCount = consoleInfo.mock.calls.length;
    cleanup();
    visualViewport.dispatchEvent(new Event("resize"));
    expect(consoleInfo).toHaveBeenCalledTimes(callCount + 1);
    expect(window.__keyboardDebugSnapshot).toBeUndefined();
    expect(window.__keyboardDebugCleanup).toBeUndefined();

    input.remove();
  });
});
