/**
 * useResponsiveValue Hook
 * 响应式值映射 - 根据当前断点返回对应值
 */

import { useMemo } from 'react';
import { useWindowDimensions } from './useScreenSize';
import { getFineBreakpoint } from './useBreakpoint';
import type { FineBreakpointKey, ResponsiveValue } from './types';

const breakpointOrder: FineBreakpointKey[] = ['4xl', '3xl', '2xl', 'xl', 'lg', 'md', 'sm', 'xs'];

/**
 * 根据当前断点从响应式值对象中选择合适的值
 * 
 * @param value - 响应式值，可以是单一值或断点映射对象
 * @returns 选中的值
 * 
 * @example
 * const padding = useResponsiveValue({ xs: 8, md: 16, lg: 24 });
 * // 在 xs 屏幕返回 8，md 屏幕返回 16，lg 及以上返回 24
 */
export function useResponsiveValue<T>(value: ResponsiveValue<T>): T {
  const { width } = useWindowDimensions();
  const fineBreakpoint = getFineBreakpoint(width);
  
  return useMemo(() => {
    // 如果不是对象，直接返回
    if (typeof value !== 'object' || value === null || Array.isArray(value)) {
      return value as T;
    }
    
    const valueMap = value as Partial<Record<FineBreakpointKey, T>>;
    
    // 从当前断点开始向下查找
    const currentIndex = breakpointOrder.indexOf(fineBreakpoint);
    for (let i = currentIndex; i < breakpointOrder.length; i++) {
      const bp = breakpointOrder[i];
      if (bp in valueMap) {
        return valueMap[bp]!;
      }
    }
    
    // 如果没找到，返回 xs 的值或第一个值
    return (valueMap.xs ?? Object.values(valueMap)[0]) as T;
  }, [value, fineBreakpoint]);
}

/**
 * 响应式样式生成器
 * 根据断点生成响应式样式
 * 
 * @param styles - 响应式样式对象
 * @returns 当前断点对应的样式
 * 
 * @example
 * const containerStyle = useResponsiveStyle({
 *   padding: { xs: 8, md: 16, lg: 24 },
 *   fontSize: { xs: 14, lg: 16 }
 * });
 */
export function useResponsiveStyle<T extends Record<string, ResponsiveValue<unknown>>>(
  styles: T
): { [K in keyof T]: T[K] extends ResponsiveValue<infer V> ? V : never } {
  const { width } = useWindowDimensions();
  const fineBreakpoint = getFineBreakpoint(width);
  
  return useMemo(() => {
    const result = {} as { [K in keyof T]: T[K] extends ResponsiveValue<infer V> ? V : never };
    
    for (const key in styles) {
      const value = styles[key];
      
      if (typeof value !== 'object' || value === null || Array.isArray(value)) {
        (result as Record<string, unknown>)[key] = value;
      } else {
        const valueMap = value as Partial<Record<FineBreakpointKey, unknown>>;
        const currentIndex = breakpointOrder.indexOf(fineBreakpoint);
        
        let selectedValue: unknown = undefined;
        for (let i = currentIndex; i < breakpointOrder.length; i++) {
          const bp = breakpointOrder[i];
          if (bp in valueMap) {
            selectedValue = valueMap[bp];
            break;
          }
        }
        
        (result as Record<string, unknown>)[key] = selectedValue ?? valueMap.xs ?? Object.values(valueMap)[0];
      }
    }
    
    return result;
  }, [styles, fineBreakpoint]);
}
