/**
 * useBreakpoint Hook
 * 断点检测 - 检测当前断点
 */

import { useMemo, useState, useEffect } from 'react';
import { Dimensions, ScaledSize } from 'react-native';
import { BREAKPOINTS, FINE_BREAKPOINTS } from './types';
import type { BreakpointKey, FineBreakpointKey } from './types';

// ==================== 工具函数 ====================

/**
 * 获取当前断点
 */
export function getBreakpoint(width: number): BreakpointKey {
  if (width >= BREAKPOINTS.wide) {
    return 'wide';
  }
  if (width >= BREAKPOINTS.desktop) {
    return 'desktop';
  }
  if (width >= BREAKPOINTS.tablet) {
    return 'tablet';
  }
  return 'mobile';
}

/**
 * 获取细粒度断点
 */
export function getFineBreakpoint(width: number): FineBreakpointKey {
  if (width >= FINE_BREAKPOINTS['4xl']) return '4xl';
  if (width >= FINE_BREAKPOINTS['3xl']) return '3xl';
  if (width >= FINE_BREAKPOINTS['2xl']) return '2xl';
  if (width >= FINE_BREAKPOINTS.xl) return 'xl';
  if (width >= FINE_BREAKPOINTS.lg) return 'lg';
  if (width >= FINE_BREAKPOINTS.md) return 'md';
  if (width >= FINE_BREAKPOINTS.sm) return 'sm';
  return 'xs';
}

/**
 * 断点比较 - 检查当前断点是否大于等于目标断点
 */
export function isBreakpointGTE(
  current: FineBreakpointKey,
  target: FineBreakpointKey
): boolean {
  const order: FineBreakpointKey[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'];
  return order.indexOf(current) >= order.indexOf(target);
}

/**
 * 断点比较 - 检查当前断点是否小于目标断点
 */
export function isBreakpointLT(
  current: FineBreakpointKey,
  target: FineBreakpointKey
): boolean {
  return !isBreakpointGTE(current, target);
}

/**
 * 检查当前是否在指定断点范围内
 */
export function isBreakpointBetween(
  current: FineBreakpointKey,
  min: FineBreakpointKey,
  max: FineBreakpointKey
): boolean {
  return isBreakpointGTE(current, min) && isBreakpointLT(current, max);
}

// ==================== Hooks ====================

function useWindowDimensionsLocal(): ScaledSize {
  const [dimensions, setDimensions] = useState(() => Dimensions.get('window'));

  useEffect(() => {
    const subscription = Dimensions.addEventListener('change', ({ window }) => {
      setDimensions(window);
    });

    return () => {
      subscription.remove();
    };
  }, []);

  return dimensions;
}

/**
 * 断点检测 Hook
 * 返回当前的基础断点
 * 
 * @returns 当前断点
 * 
 * @example
 * const breakpoint = useBreakpoint();
 * // 'mobile' | 'tablet' | 'desktop' | 'wide'
 */
export function useBreakpoint(): BreakpointKey {
  const { width } = useWindowDimensionsLocal();
  
  return useMemo(() => {
    return getBreakpoint(width);
  }, [width]);
}

/**
 * 细粒度断点检测 Hook
 * 返回当前的细粒度断点
 * 
 * @returns 当前细粒度断点
 * 
 * @example
 * const fineBreakpoint = useFineBreakpoint();
 * // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl'
 */
export function useFineBreakpoint(): FineBreakpointKey {
  const { width } = useWindowDimensionsLocal();
  
  return useMemo(() => {
    return getFineBreakpoint(width);
  }, [width]);
}

/**
 * 检查当前断点是否大于等于目标断点
 * 
 * @param target - 目标断点
 * @returns 是否满足条件
 * 
 * @example
 * const isMediumUp = useBreakpointGTE('md');
 */
export function useBreakpointGTE(target: FineBreakpointKey): boolean {
  const { width } = useWindowDimensionsLocal();
  
  return useMemo(() => {
    const current = getFineBreakpoint(width);
    return isBreakpointGTE(current, target);
  }, [width, target]);
}

/**
 * 检查当前断点是否小于目标断点
 * 
 * @param target - 目标断点
 * @returns 是否满足条件
 * 
 * @example
 * const isMobileOnly = useBreakpointLT('lg');
 */
export function useBreakpointLT(target: FineBreakpointKey): boolean {
  const { width } = useWindowDimensionsLocal();
  
  return useMemo(() => {
    const current = getFineBreakpoint(width);
    return isBreakpointLT(current, target);
  }, [width, target]);
}

/**
 * 检查当前是否在指定断点范围内
 * 
 * @param min - 最小断点（包含）
 * @param max - 最大断点（不包含）
 * @returns 是否在范围内
 * 
 * @example
 * const isTabletRange = useBreakpointBetween('md', 'lg');
 */
export function useBreakpointBetween(
  min: FineBreakpointKey,
  max: FineBreakpointKey
): boolean {
  const { width } = useWindowDimensionsLocal();
  
  return useMemo(() => {
    const current = getFineBreakpoint(width);
    return isBreakpointBetween(current, min, max);
  }, [width, min, max]);
}

export default {
  useBreakpoint,
  useFineBreakpoint,
  useBreakpointGTE,
  useBreakpointLT,
  useBreakpointBetween,
};
