"use client";

import React, { useEffect, useState, useCallback, useRef } from "react";

interface KeyboardState {
  isVisible: boolean;
  height: number;
  duration: number;
  easing: string;
}

interface ViewportInfo {
  width: number;
  height: number;
  visualHeight: number;
  keyboardHeight: number;
}

interface MobileKeyboardHandlerProps {
  children: React.ReactNode;
  onKeyboardToggle?: (isVisible: boolean, height: number) => void;
  adjustmentStrategy?: "resize" | "scroll" | "shrink";
  className?: string;
  enableSafeArea?: boolean;
  minVisibleHeight?: number;
}

// Hook for detecting keyboard visibility and viewport changes
export function useKeyboardDetection(): KeyboardState & ViewportInfo {
  const [keyboardState, setKeyboardState] = useState<KeyboardState>({
    isVisible: false,
    height: 0,
    duration: 300,
    easing: "ease-out",
  });

  const [viewportInfo, setViewportInfo] = useState<ViewportInfo>({
    width: 0,
    height: 0,
    visualHeight: 0,
    keyboardHeight: 0,
  });

  useEffect(() => {
    if (typeof window === "undefined") return;

    let initialHeight = window.innerHeight;
    let initialWidth = window.innerWidth;

    const updateViewport = () => {
      const currentHeight = window.innerHeight;
      const currentWidth = window.innerWidth;

      // Use Visual Viewport API if available
      let visualViewportHeight = currentHeight;
      if ("visualViewport" in window && window.visualViewport) {
        visualViewportHeight = window.visualViewport.height;
      }

      const keyboardHeight = Math.max(0, initialHeight - visualViewportHeight);
      const keyboardVisible = keyboardHeight > 150; // Threshold for keyboard detection

      setKeyboardState((prev) => ({
        ...prev,
        isVisible: keyboardVisible,
        height: keyboardHeight,
      }));

      setViewportInfo({
        width: currentWidth,
        height: currentHeight,
        visualHeight: visualViewportHeight,
        keyboardHeight,
      });
    };

    // Handle orientation changes
    const handleOrientationChange = () => {
      // Wait for orientation change to complete
      setTimeout(() => {
        initialHeight = window.innerHeight;
        initialWidth = window.innerWidth;
        updateViewport();
      }, 500);
    };

    // Multiple event listeners for comprehensive coverage
    const events = ["resize", "orientationchange"];
    events.forEach((event) => {
      window.addEventListener(event, updateViewport);
    });

    // Special handling for orientation change
    window.addEventListener("orientationchange", handleOrientationChange);

    // Visual Viewport API listeners
    if ("visualViewport" in window && window.visualViewport) {
      window.visualViewport.addEventListener("resize", updateViewport);
      window.visualViewport.addEventListener("scroll", updateViewport);
    }

    // iOS specific handling
    if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
      // iOS specific events
      document.addEventListener("focusin", updateViewport);
      document.addEventListener("focusout", updateViewport);
    }

    // Initial update
    updateViewport();

    return () => {
      events.forEach((event) => {
        window.removeEventListener(event, updateViewport);
      });

      window.removeEventListener("orientationchange", handleOrientationChange);

      if ("visualViewport" in window && window.visualViewport) {
        window.visualViewport.removeEventListener("resize", updateViewport);
        window.visualViewport.removeEventListener("scroll", updateViewport);
      }

      if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
        document.removeEventListener("focusin", updateViewport);
        document.removeEventListener("focusout", updateViewport);
      }
    };
  }, []);

  return { ...keyboardState, ...viewportInfo };
}

// Hook for managing input focus and keyboard behavior
export function useMobileInputFocus() {
  const scrollToInput = useCallback((inputElement: HTMLElement) => {
    if (!inputElement) return;

    // Prevent default zoom behavior on iOS
    const originalFontSize = inputElement.style.fontSize;
    const originalViewport = document.querySelector('meta[name="viewport"]');

    // Temporarily set font size to prevent zoom
    inputElement.style.fontSize = "16px";

    // Scroll input into view
    setTimeout(() => {
      inputElement.scrollIntoView({
        behavior: "smooth",
        block: "center",
        inline: "nearest",
      });

      // Focus the input
      inputElement.focus();

      // Restore original font size
      if (originalFontSize) {
        inputElement.style.fontSize = originalFontSize;
      }
    }, 100);
  }, []);

  const preventZoom = useCallback((inputElement: HTMLInputElement) => {
    // Prevent zoom on input focus (iOS)
    const currentFontSize = window.getComputedStyle(inputElement).fontSize;
    const fontSize = parseFloat(currentFontSize);

    if (fontSize < 16) {
      inputElement.style.fontSize = "16px";
      inputElement.style.transform = `scale(${fontSize / 16})`;
      inputElement.style.transformOrigin = "left center";
    }
  }, []);

  const handleInputFocus = useCallback(
    (event: React.FocusEvent<HTMLInputElement>) => {
      const input = event.target;
      preventZoom(input);
      scrollToInput(input);
    },
    [preventZoom, scrollToInput]
  );

  return { scrollToInput, preventZoom, handleInputFocus };
}

// Component for handling keyboard adjustments
export function MobileKeyboardHandler({
  children,
  onKeyboardToggle,
  adjustmentStrategy = "resize",
  className = "",
  enableSafeArea = true,
  minVisibleHeight = 200,
}: MobileKeyboardHandlerProps) {
  const keyboard = useKeyboardDetection();
  const containerRef = useRef<HTMLDivElement>(null);

  // Notify parent of keyboard changes
  useEffect(() => {
    onKeyboardToggle?.(keyboard.isVisible, keyboard.height);
  }, [keyboard.isVisible, keyboard.height, onKeyboardToggle]);

  // Apply adjustments based on strategy
  const getContainerStyle = useCallback((): React.CSSProperties => {
    const baseStyle: React.CSSProperties = {
      position: "relative",
      transition: `all ${keyboard.duration}ms ${keyboard.easing}`,
      width: "100%",
    };

    if (!keyboard.isVisible) {
      return {
        ...baseStyle,
        height: "100vh",
        maxHeight: "100vh",
      };
    }

    switch (adjustmentStrategy) {
      case "resize":
        return {
          ...baseStyle,
          height: `${keyboard.visualHeight}px`,
          maxHeight: `${keyboard.visualHeight}px`,
          overflow: "hidden",
        };

      case "scroll":
        return {
          ...baseStyle,
          height: "100vh",
          paddingBottom: `${keyboard.keyboardHeight}px`,
          overflowY: "auto",
        };

      case "shrink":
        const availableHeight = Math.max(
          keyboard.visualHeight,
          minVisibleHeight
        );
        return {
          ...baseStyle,
          height: `${availableHeight}px`,
          maxHeight: `${availableHeight}px`,
          transform: keyboard.isVisible
            ? `translateY(-${Math.max(
                0,
                keyboard.keyboardHeight - (keyboard.height - availableHeight)
              )}px)`
            : "translateY(0)",
        };

      default:
        return baseStyle;
    }
  }, [
    keyboard.isVisible,
    keyboard.visualHeight,
    keyboard.keyboardHeight,
    keyboard.height,
    keyboard.duration,
    keyboard.easing,
    adjustmentStrategy,
    minVisibleHeight,
  ]);

  // Apply safe area styles for devices with notches
  const getSafeAreaStyle = useCallback((): React.CSSProperties => {
    if (!enableSafeArea) return {};

    return {
      paddingTop: "env(safe-area-inset-top)",
      paddingLeft: "env(safe-area-inset-left)",
      paddingRight: "env(safe-area-inset-right)",
      paddingBottom: keyboard.isVisible ? "0" : "env(safe-area-inset-bottom)",
    };
  }, [enableSafeArea, keyboard.isVisible]);

  return (
    <div
      ref={containerRef}
      className={`mobile-keyboard-handler ${className}`}
      style={{
        ...getContainerStyle(),
        ...getSafeAreaStyle(),
      }}
      data-keyboard-visible={keyboard.isVisible}
      data-keyboard-height={keyboard.height}
    >
      {children}
    </div>
  );
}

// Enhanced input component with keyboard handling
interface KeyboardAwareInputProps {
  value: string;
  onChange: (value: string) => void;
  onSubmit?: () => void;
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  autoFocus?: boolean;
  keepVisible?: boolean;
}

export function KeyboardAwareInput({
  value,
  onChange,
  onSubmit,
  placeholder,
  disabled = false,
  className = "",
  autoFocus = false,
  keepVisible = true,
}: KeyboardAwareInputProps) {
  const inputRef = useRef<HTMLInputElement>(null);
  const { handleInputFocus } = useMobileInputFocus();
  const keyboard = useKeyboardDetection();

  // Keep input visible when keyboard appears
  useEffect(() => {
    if (keepVisible && keyboard.isVisible && inputRef.current) {
      const input = inputRef.current;
      const inputRect = input.getBoundingClientRect();
      const viewportHeight = keyboard.visualHeight;

      // Check if input is hidden by keyboard
      if (inputRect.bottom > viewportHeight) {
        input.scrollIntoView({
          behavior: "smooth",
          block: "end",
        });
      }
    }
  }, [keyboard.isVisible, keyboard.visualHeight, keepVisible]);

  const handleKeyPress = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter" && onSubmit) {
        e.preventDefault();
        onSubmit();
      }
    },
    [onSubmit]
  );

  return (
    <input
      ref={inputRef}
      type="text"
      value={value}
      onChange={(e) => onChange(e.target.value)}
      onKeyPress={handleKeyPress}
      onFocus={handleInputFocus}
      placeholder={placeholder}
      disabled={disabled}
      autoFocus={autoFocus}
      className={className}
      style={{
        fontSize: "16px", // Prevent zoom on iOS
        minHeight: "48px",
        padding: "12px 16px",
        borderRadius: "24px",
        border: "2px solid #e1e5e9",
        outline: "none",
        width: "100%",
        backgroundColor: "#f8f9fa",
        transition: "border-color 0.2s ease",
        touchAction: "manipulation",
        WebkitAppearance: "none", // Remove iOS styling
      }}
    />
  );
}

// Hook for back button handling (Android/Browser)
export function useBackButtonHandler(onBackPress?: () => void) {
  useEffect(() => {
    if (typeof window === "undefined" || !onBackPress) return;

    // Handle browser back button
    const handlePopState = (event: PopStateEvent) => {
      event.preventDefault();
      onBackPress();
    };

    // Push a state to handle back button
    window.history.pushState({ modal: true }, "", "");
    window.addEventListener("popstate", handlePopState);

    return () => {
      window.removeEventListener("popstate", handlePopState);
      // Clean up history state if still on the same state
      if (window.history.state?.modal) {
        window.history.back();
      }
    };
  }, [onBackPress]);
}

// Hook for preventing body scroll when modal is open
export function useScrollLock(isLocked: boolean) {
  useEffect(() => {
    if (typeof document === "undefined") return;

    const body = document.body;
    const scrollBarWidth =
      window.innerWidth - document.documentElement.clientWidth;

    if (isLocked) {
      const originalStyle = window.getComputedStyle(body);
      const originalTop = body.style.top;
      const originalPosition = body.style.position;
      const originalOverflow = body.style.overflow;
      const originalPaddingRight = body.style.paddingRight;

      // Lock scroll
      body.style.overflow = "hidden";
      body.style.paddingRight = `${scrollBarWidth}px`;

      // iOS specific fixes
      if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
        const scrollTop =
          window.pageYOffset || document.documentElement.scrollTop;
        body.style.position = "fixed";
        body.style.top = `-${scrollTop}px`;
        body.style.left = "0";
        body.style.right = "0";
      }

      return () => {
        // Restore scroll
        body.style.overflow = originalOverflow;
        body.style.paddingRight = originalPaddingRight;

        if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
          body.style.position = originalPosition;
          body.style.top = originalTop;
          body.style.left = "";
          body.style.right = "";

          // Restore scroll position
          const top = parseInt(originalTop || "0", 10) * -1;
          window.scrollTo(0, top);
        }
      };
    }
  }, [isLocked]);
}
