import React from 'react';
import { Image as RNImage, ImageProps as RNImageProps, View, Text } from 'react-native';
import { getImageSourceWithDefault, isLocalPath, convertLocalPathToUri } from '@/utils/image';
import { getGameImageSizeFromPath } from '@/constants/gameImages';

/**
 * 自定义 Image 组件
 *
 * 功能：
 * - 自动处理图片 URL 验证
 * - 支持默认图片
 * - 支持自适应宽度或高度
 * - 支持自动测量图片尺寸（无需预知 aspectRatio）
 * - 简化图片加载逻辑
 *
 * 使用方式：
 * ```typescript
 * // 基础用法
 * <Image
 *   source="https://example.com/image.png"
 *   defaultSource="https://via.placeholder.com/200"
 *   style={{ width: 100, height: 100 }}
 * />
 *
 * // 设置高度，宽度自适应（需要提供 aspectRatio）
 * <Image
 *   source="https://example.com/image.png"
 *   style={{ height: 200 }}  // 只设置高度
 *   aspectRatio={16 / 9}
 *   adaptiveMode="height"
 * />
 *
 * // 设置宽度，高度自适应（需要提供 aspectRatio）
 * <Image
 *   source="https://example.com/image.png"
 *   style={{ width: 300 }}  // 只设置宽度
 *   aspectRatio={4 / 3}
 *   adaptiveMode="width"
 * />
 *
 * // 自动测量图片尺寸（推荐用于未知尺寸的图片）
 * <Image
 *   source="https://example.com/image.png"
 *   style={{ height: 50 }}
 *   adaptiveMode="height"
 *   autoMeasure={true}
 * />
 * ```
 */

interface CustomImageProps extends Omit<RNImageProps, 'source' | 'defaultSource'> {
  /** 图片 URL（HTTP/HTTPS 或 Data URI） */
  source?: string;
  /** 默认图片 URL（当主图片无效时使用） */
  defaultSource?: string;
  /** 是否显示加载失败的占位符 */
  showPlaceholder?: boolean;
  /** 图片宽高比（用于自适应宽度或高度） */
  aspectRatio?: number;
  /** 自适应模式：
   * - 'height': 高度固定，宽度自适应（style 中只需设置 height）
   * - 'width': 宽度固定，高度自适应（style 中只需设置 width）
   */
  adaptiveMode?: 'width' | 'height';
  /** 是否自动测量图片尺寸（当 aspectRatio 未提供时） */
  autoMeasure?: boolean;
}

const Image = React.forwardRef<RNImage, CustomImageProps>(
  (
    {
      source,
      defaultSource = 'https://via.placeholder.com/200',
      showPlaceholder = false,
      style,
      aspectRatio,
      adaptiveMode,
      autoMeasure = false,
      onLoad,
      ...props
    },
    ref
  ) => {
    // 自动测量的宽高比状态
    const [measuredAspectRatio, setMeasuredAspectRatio] = React.useState<number | null>(null);

    // 获取有效的图片 URI
    const imageUri = getImageSourceWithDefault(source, defaultSource);

    // 处理图片加载完成事件
    const handleImageLoad = React.useCallback(
      (event: any) => {
        if (autoMeasure) {
          try {
            // 尝试从不同的位置获取图片尺寸
            let width: number | undefined;
            let height: number | undefined;

            // 方式 1: event.nativeEvent.source
            if (event?.nativeEvent?.source) {
              width = event.nativeEvent.source.width;
              height = event.nativeEvent.source.height;
            }

            // 方式 2: event.nativeEvent
            if (!width || !height) {
              width = event?.nativeEvent?.width;
              height = event?.nativeEvent?.height;
            }

            // 方式 3: 直接从 event
            if (!width || !height) {
              width = event?.width;
              height = event?.height;
            }

            if (width && height && typeof width === 'number' && typeof height === 'number') {
              const ratio = width / height;
              setMeasuredAspectRatio(ratio);
              if (__DEV__) {
                console.log(
                  `[Image] Measured dimensions from event: ${width}x${height}, ratio: ${ratio.toFixed(3)}`
                );
              }
            } else {
              // 如果从 event 获取失败，尝试从本地路径的映射表获取
              if (isLocalPath(source)) {
                const size = getGameImageSizeFromPath(source);
                if (size && size.width && size.height) {
                  const ratio = size.width / size.height;
                  setMeasuredAspectRatio(ratio);
                  if (__DEV__) {
                    console.log(
                      `[Image] Measured dimensions from mapping: ${size.width}x${size.height}, ratio: ${ratio.toFixed(3)}`
                    );
                  }
                } else if (__DEV__) {
                  console.warn(
                    `[Image] Failed to get dimensions from event or mapping for: ${source}`
                  );
                }
              } else if (__DEV__) {
                console.warn(
                  `[Image] Failed to get dimensions from event. Event:`,
                  JSON.stringify(event, null, 2)
                );
              }
            }
          } catch (error) {
            // 忽略获取尺寸的错误
            console.warn('Failed to measure image dimensions:', error);
          }
        }
        onLoad?.(event);
      },
      [autoMeasure, onLoad, source]
    );

    // 计算自适应样式
    const adaptiveStyle = React.useMemo(() => {
      // 优先使用提供的 aspectRatio，其次使用测量的 aspectRatio
      const ratio = aspectRatio || (autoMeasure ? measuredAspectRatio : null);

      if (!ratio || !adaptiveMode) {
        return {};
      }

      // 从 style 中提取宽度和高度
      const styleObj = Array.isArray(style) ? Object.assign({}, ...style) : style || {};
      const fixedWidth = styleObj.width;
      const fixedHeight = styleObj.height;

      // adaptiveMode 的含义：
      // - 'height': 高度固定，宽度自适应
      //   计算方式：width = height * aspectRatio
      // - 'width': 宽度固定，高度自适应
      //   计算方式：height = width / aspectRatio

      if (adaptiveMode === 'height' && fixedHeight) {
        // 高度固定，计算宽度
        // 注意：不返回 aspectRatio，让宽高完全由计算值决定
        // 这样可以避免 resizeMode 对宽高比的影响
        const calculatedWidth = fixedHeight * ratio;
        if (__DEV__) {
          console.log(
            `[Image] adaptiveMode=height: fixedHeight=${fixedHeight}, ratio=${ratio.toFixed(3)}, calculatedWidth=${calculatedWidth.toFixed(1)}`
          );
        }
        return {
          width: calculatedWidth,
          height: fixedHeight,
        };
      } else if (adaptiveMode === 'width' && fixedWidth) {
        // 宽度固定，计算高度
        // 注意：不返回 aspectRatio，让宽高完全由计算值决定
        const calculatedHeight = fixedWidth / ratio;
        if (__DEV__) {
          console.log(
            `[Image] adaptiveMode=width: fixedWidth=${fixedWidth}, ratio=${ratio.toFixed(3)}, calculatedHeight=${calculatedHeight.toFixed(1)}`
          );
        }
        return {
          width: fixedWidth,
          height: calculatedHeight,
        };
      }

      // 如果没有固定值，仅使用 aspectRatio
      return { aspectRatio: ratio };
    }, [aspectRatio, adaptiveMode, autoMeasure, measuredAspectRatio, style]);

    // 如果没有有效的图片 URI，显示占位符
    if (!imageUri) {
      if (showPlaceholder) {
        return (
          <View
            style={[
              {
                backgroundColor: '#f0f0f0',
                justifyContent: 'center',
                alignItems: 'center',
              },
              style,
              adaptiveStyle,
            ]}
          >
            <Text style={{ color: '#999', fontSize: 12 }}>图片加载失败</Text>
          </View>
        );
      }
      return null;
    }

    // 处理本地路径和外部 URL
    let imageSource: any;

    if (isLocalPath(imageUri)) {
      // 本地路径：/images/game/chess/color_101.png
      // 转换为 require 对象
      const localSource = convertLocalPathToUri(imageUri);
      imageSource = localSource || { uri: defaultSource };
    } else {
      // 外部 URL
      imageSource = { uri: imageUri };
    }

    return (
      <RNImage
        ref={ref}
        source={imageSource}
        style={[style]}
        onLoad={handleImageLoad}
        {...props}
      />
    );
  }
);

Image.displayName = 'Image';

export default Image;
