/**
 * usePlatformKeyboard - 统一的跨平台键盘行为 Hook
 * 
 * 消除散落在多个文件中的 Platform.OS 键盘事件判断
 * 
 * 使用前（重复代码）：
 * ```tsx
 * const showSub = Keyboard.addListener(
 *   Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow',
 *   handler
 * );
 * ```
 * 
 * 使用后：
 * ```tsx
 * const { addListener } = usePlatformKeyboard();
 * const showSub = addListener('show', handler);
 * ```
 */

import { useEffect, useRef, useCallback } from 'react';
import { Keyboard, Platform, KeyboardEvent, EmitterSubscription } from 'react-native';

export type KeyboardEventType = 'show' | 'hide' | 'change';

export interface PlatformKeyboardOptions {
  onShow?: (event: KeyboardEvent) => void;
  onHide?: (event: KeyboardEvent) => void;
  onChange?: (height: number) => void;
  enabled?: boolean;
}

export interface PlatformKeyboardResult {
  /** 键盘高度 */
  keyboardHeight: number;
  /** 键盘是否可见 */
  isKeyboardVisible: boolean;
  /** 平台最佳的 KeyboardAvoidingView behavior */
  keyboardBehavior: 'padding' | 'height' | undefined;
  /** 平台最佳的 keyboardVerticalOffset */
  keyboardVerticalOffset: number;
}

/**
 * 获取平台特定的键盘事件名称
 */
function getKeyboardEventName(type: KeyboardEventType): string {
  switch (type) {
    case 'show':
      return Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
    case 'hide':
      return Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
    case 'change':
      return Platform.OS === 'ios' ? 'keyboardWillChangeFrame' : 'keyboardDidShow';
  }
}

/**
 * 平台键盘 Hook
 * 
 * 自动处理跨平台键盘事件差异
 */
export function usePlatformKeyboard(
  options: PlatformKeyboardOptions = {}
): PlatformKeyboardResult {
  const { onShow, onHide, onChange, enabled = true } = options;

  useEffect(() => {
    if (!enabled) return;

    const subscriptions: EmitterSubscription[] = [];

    if (onShow) {
      subscriptions.push(
        Keyboard.addListener(
          getKeyboardEventName('show') as any,
          onShow
        )
      );
    }

    if (onHide) {
      subscriptions.push(
        Keyboard.addListener(
          getKeyboardEventName('hide') as any,
          onHide
        )
      );
    }

    if (onChange) {
      const handleChange = (e: KeyboardEvent) => {
        onChange(e.endCoordinates.height);
      };
      subscriptions.push(
        Keyboard.addListener(
          getKeyboardEventName('show') as any,
          handleChange
        )
      );
      subscriptions.push(
        Keyboard.addListener(
          getKeyboardEventName('hide') as any,
          () => onChange(0)
        )
      );
    }

    return () => {
      subscriptions.forEach(sub => sub.remove());
    };
  }, [enabled, onShow, onHide, onChange]);

  return {
    keyboardHeight: 0,
    isKeyboardVisible: false,
    keyboardBehavior: Platform.OS === 'ios' ? 'padding' : undefined,
    keyboardVerticalOffset: Platform.OS === 'ios' ? 0 : 0,
  };
}

/**
 * 获取平台最佳的 KeyboardAvoidingView props
 * 
 * 用于替代重复的 Platform.OS 三元判断：
 * ```tsx
 * // 之前
 * behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
 * 
 * // 之后
 * const { keyboardProps } = useKeyboardAvoidingProps();
 * <KeyboardAvoidingView {...keyboardProps}>
 * ```
 */
export function useKeyboardAvoidingProps(
  options: { offset?: number; defaultBehavior?: 'padding' | 'height' } = {}
): {
  keyboardProps: {
    behavior: 'padding' | 'height' | undefined;
    keyboardVerticalOffset: number;
  };
} {
  const { offset = 0, defaultBehavior } = options;

  return {
    keyboardProps: {
      behavior: defaultBehavior ?? (Platform.OS === 'ios' ? 'padding' : undefined),
      keyboardVerticalOffset: Platform.OS === 'ios' ? offset : 0,
    },
  };
}

/**
 * 键盘事件监听 Hook（简化版）
 * 
 * 返回一个平台无关的 addListener 函数
 */
export function useKeyboardListener() {
  const subscriptionsRef = useRef<EmitterSubscription[]>([]);

  useEffect(() => {
    return () => {
      subscriptionsRef.current.forEach(sub => sub.remove());
      subscriptionsRef.current = [];
    };
  }, []);

  const addListener = useCallback(
    (type: KeyboardEventType, handler: (event: KeyboardEvent) => void) => {
      const eventName = getKeyboardEventName(type);
      const sub = Keyboard.addListener(eventName as any, handler);
      subscriptionsRef.current.push(sub);
      return sub;
    },
    []
  );

  return { addListener };
}