"use client";

import { useEffect, type RefObject } from "react";

import {
  observeBrowserViewport,
  readBrowserViewportMetrics,
} from "@/lib/browser/viewport_observer";
import { BrowserDetector } from "@/utils/browser-detect";
import { PlatformDetector } from "@/utils/platform-detect";

const CHAT_KEYBOARD_DEBUG_PARAM = "keyboard_debug";

export interface ChatKeyboardDebugSnapshot {
  event: string;
  time: number;
  windowInnerHeight: number;
  documentClientHeight: number;
  scrollY: number;
  visualViewportSupported: boolean;
  visualHeight: number | null;
  visualWidth: number | null;
  visualOffsetTop: number | null;
  visualOffsetLeft: number | null;
  visualScale: number | null;
  virtualKeyboardSupported: boolean;
  virtualKeyboardOverlaysContent: boolean | null;
  virtualKeyboardRect: {
    x: number;
    y: number;
    width: number;
    height: number;
  } | null;
  activeElement: string | null;
  activeBottom: number | null;
  activeFocused: boolean;
  inputBarTop: number | null;
  inputBarBottom: number | null;
  inputBarPaddingBottom: string | null;
  keyboardBottomInset: string | null;
  appViewportHeight: string | null;
  appVisibleHeight: string | null;
  appVisibleOffsetTop: string | null;
  viewportMeta: string | null;
  platform: {
    name: string;
    osName: string;
    osVersion: string;
    deviceVendor: string;
    deviceModel: string;
  };
  browser: {
    name: string;
    version: string;
    inAppBrowserName: string | null;
  };
}

declare global {
  interface Window {
    __keyboardDebugCleanup?: () => void;
    __keyboardDebugSnapshot?: () => ChatKeyboardDebugSnapshot;
  }
}

export interface UseChatKeyboardDiagnosticsOptions {
  containerRef: RefObject<HTMLElement | null>;
}

export function useChatKeyboardDiagnostics({
  containerRef,
}: UseChatKeyboardDiagnosticsOptions): void {
  useEffect(() => {
    if (!isChatKeyboardDiagnosticsEnabled(window.location.search)) return;
    return installChatKeyboardDiagnostics(containerRef);
  }, [containerRef]);
}

export function isChatKeyboardDiagnosticsEnabled(search: string): boolean {
  return new URLSearchParams(search).get(CHAT_KEYBOARD_DEBUG_PARAM) === "1";
}

export function installChatKeyboardDiagnostics(
  containerRef: RefObject<HTMLElement | null>,
): () => void {
  window.__keyboardDebugCleanup?.();

  const removers: Array<() => void> = [];
  let disposed = false;

  const takeSnapshot = (event: string): ChatKeyboardDebugSnapshot => {
    const snapshot = createChatKeyboardDebugSnapshot(event, containerRef);
    window.console.info("[keyboard-debug]", snapshot);
    return snapshot;
  };

  const cleanup = () => {
    if (disposed) return;
    disposed = true;
    removers.forEach((remove) => remove());
    if (window.__keyboardDebugSnapshot === manualSnapshot) {
      delete window.__keyboardDebugSnapshot;
    }
    if (window.__keyboardDebugCleanup === cleanup) {
      delete window.__keyboardDebugCleanup;
    }
    window.console.info("[keyboard-debug] removed");
  };
  const manualSnapshot = () => takeSnapshot("manual");
  removers.push(
    observeBrowserViewport(
      (observation) => takeSnapshot(observation.reason),
      { emitInitial: false },
    ),
  );

  window.__keyboardDebugSnapshot = manualSnapshot;
  window.__keyboardDebugCleanup = cleanup;
  takeSnapshot("installed");

  return cleanup;
}

function createChatKeyboardDebugSnapshot(
  event: string,
  containerRef: RefObject<HTMLElement | null>,
): ChatKeyboardDebugSnapshot {
  const metrics = readBrowserViewportMetrics();
  const activeElement = document.activeElement;
  const activeRect =
    activeElement instanceof HTMLElement
      ? activeElement.getBoundingClientRect()
      : null;
  const platform = PlatformDetector.getPlatformInfo();
  const browser = BrowserDetector.getBrowserInfo();
  const rootStyle = document.documentElement.style;
  const inputBar = containerRef.current;
  const inputBarRect = inputBar?.getBoundingClientRect() ?? null;
  const inputBarStyle = inputBar ? window.getComputedStyle(inputBar) : null;

  return {
    event,
    time: Math.round(performance.now()),
    windowInnerHeight: metrics.layoutHeight,
    documentClientHeight: metrics.documentClientHeight,
    scrollY: metrics.scrollY,
    visualViewportSupported: metrics.visualViewportSupported,
    visualHeight: metrics.visualViewportSupported
      ? metrics.visualHeight
      : null,
    visualWidth: metrics.visualViewportSupported
      ? metrics.visualWidth
      : null,
    visualOffsetTop: metrics.visualViewportSupported
      ? metrics.visualOffsetTop
      : null,
    visualOffsetLeft: metrics.visualViewportSupported
      ? metrics.visualOffsetLeft
      : null,
    visualScale: metrics.visualViewportSupported
      ? metrics.visualScale
      : null,
    virtualKeyboardSupported: metrics.virtualKeyboardSupported,
    virtualKeyboardOverlaysContent:
      metrics.virtualKeyboardOverlaysContent,
    virtualKeyboardRect: metrics.virtualKeyboardRect,
    activeElement: activeElement?.tagName ?? null,
    activeBottom: activeRect?.bottom ?? null,
    activeFocused: activeElement !== document.body,
    inputBarTop: inputBarRect?.top ?? null,
    inputBarBottom: inputBarRect?.bottom ?? null,
    inputBarPaddingBottom: inputBarStyle?.paddingBottom ?? null,
    keyboardBottomInset:
      inputBar?.style.getPropertyValue("--chat-keyboard-bottom-inset") || null,
    appViewportHeight:
      rootStyle.getPropertyValue("--app-viewport-height") || null,
    appVisibleHeight:
      rootStyle.getPropertyValue("--app-visible-height") || null,
    appVisibleOffsetTop:
      rootStyle.getPropertyValue("--app-visible-offset-top") || null,
    viewportMeta:
      document.querySelector<HTMLMetaElement>('meta[name="viewport"]')
        ?.content ?? null,
    platform: {
      name: platform.platform,
      osName: platform.osName,
      osVersion: platform.osVersion,
      deviceVendor: platform.deviceVendor,
      deviceModel: platform.deviceModel,
    },
    browser: {
      name: browser.name,
      version: browser.version,
      inAppBrowserName: browser.inAppBrowserName,
    },
  };
}
