import { useCallback, useRef, useEffect } from 'react';
import { Platform } from 'react-native';
import LocationService from '@/services/location';
import { LOCATION_CONFIG } from '@/constants/location';

/**
 * 位置相关的 Hook
 * 提供获取当前位置、开始/停止位置监听等功能
 * 支持持续位置监听，自动管理生命周期
 */
export const useLocation = () => {
  const watchSubscriptionRef = useRef(null);
  const isWatchingRef = useRef(false);

  /**
   * 检查错误是否为不可重试的权限或设置错误
   * @param {Error} error 错误对象
   * @returns {boolean} 是否为不可重试错误
   */
  const isNonRetryableError = useCallback((error) => {
    const nonRetryableCodes = [
      // 来自 expo/nativemodules 的历史错误码（兼容）
      'E_LOCATION_UNAUTHORIZED',
      'E_LOCATION_SETTINGS_UNSATISFIED',
      // 标准化错误码（LocationService 统一产出）
      'PERMISSION_DENIED',
      'UNAVAILABLE',
      'SERVICE_DISABLED',
    ];
    const nonRetryableKeywords = ['权限', '设置', 'Permission', 'GPS', '定位服务', '位置服务'];
    
    return (nonRetryableCodes.includes(error?.code)) || 
           (typeof error?.message === 'string' && nonRetryableKeywords.some(keyword => error.message.includes(keyword)));
  }, []);

  /**
   * 获取当前位置（带重试机制和指数退避）
   * @param {Object} options 定位选项
   * @param {number} maxRetries 最大重试次数
   * @param {string} scenario 使用场景
   * @returns {Promise<Object>} 位置信息
   */
  const getCurrentLocation = useCallback(async (options = {}, maxRetries = 2, scenario = 'ATTENDANCE') => {
    const scenarioConfig = LOCATION_CONFIG[scenario] || LOCATION_CONFIG.ATTENDANCE;
    const finalMaxRetries = maxRetries !== undefined ? maxRetries : scenarioConfig.maxRetries || 2;
    const baseDelay = scenarioConfig.retryBaseDelay || 1000;
    const finalOptions = { ...scenarioConfig, ...options };
    
    let lastError;
    
    for (let attempt = 0; attempt <= finalMaxRetries; attempt++) {
      try {
        const position = await LocationService.getCurrentPosition(finalOptions);
      
        return position;
      } catch (error) {
        lastError = error;
        console.warn(`[useLocation] 定位尝试 ${attempt + 1}/${finalMaxRetries + 1} 失败:`, error?.message);
        
        // 权限或设置错误直接抛出，不重试
        if (isNonRetryableError(error)) {
          throw error;
        }
        
        // 安卓特定错误处理（兼容历史错误码）
        if (Platform.OS === 'android' && error?.code === 'E_LOCATION_SETTINGS_UNSATISFIED') {
          const e = new Error('位置服务设置不满足要求，请检查GPS设置');
          e.code = 'UNAVAILABLE';
          throw e;
        }
        
        // 如果还有重试机会，使用指数退避策略
        if (attempt < finalMaxRetries) {
          const retryDelay = Math.min(baseDelay * Math.pow(2, attempt), 5000); // 最大延迟5秒
    
          await new Promise(resolve => setTimeout(resolve, retryDelay));
        }
      }
    }
    
    throw lastError;
  }, [isNonRetryableError]);

  /**
   * 开始持续监听位置变化（防重复启动）
   * @param {Function} callback 位置变化回调函数
   * @param {Object} options 监听选项
   * @param {string} scenario 使用场景
   */
  const startWatchingLocation = useCallback(async (callback = () => {}, options = {}, scenario = 'ATTENDANCE') => {
    try {
      // 防止重复启动
      if (isWatchingRef.current) {
        return watchSubscriptionRef.current;
      }
      
      // 如果有残留订阅，先清理
      if (watchSubscriptionRef.current) {
        await stopWatchingLocation();
      }
      
      const scenarioConfig = LOCATION_CONFIG[scenario] || LOCATION_CONFIG.ATTENDANCE;
      const finalOptions = { ...scenarioConfig, ...options };

      isWatchingRef.current = true;
      
      watchSubscriptionRef.current = await LocationService.startWatchingPosition(
        (location) => {
          try {
            callback(location);
          } catch (cbError) {
            console.error('[useLocation] 位置回调执行失败:', cbError);
          }
        },
        finalOptions
      );
      return watchSubscriptionRef.current;
    } catch (error) {
      console.error('[useLocation] 开始监听位置失败:', error);
      isWatchingRef.current = false;
      watchSubscriptionRef.current = null;
      throw error;
    }
  }, []);
  
  /**
   * 停止持续监听位置变化
   */
  const stopWatchingLocation = useCallback(async () => {
    try {
      if (watchSubscriptionRef.current) {
        LocationService.stopWatchingPosition();
        watchSubscriptionRef.current = null;
        isWatchingRef.current = false;
      }
    } catch (error) {
      console.error('[useLocation] 停止监听位置失败:', error);
      // 强制清空引用
      watchSubscriptionRef.current = null;
      isWatchingRef.current = false;
    }
  }, []);
  
  /**
   * 检查是否正在监听位置
   */
  const isWatching = useCallback(() => {
    return isWatchingRef.current && watchSubscriptionRef.current !== null;
  }, []);

  // 组件卸载时清理位置监听
  useEffect(() => {
    return () => {
      if (watchSubscriptionRef.current) {
        LocationService.stopWatchingPosition();
        watchSubscriptionRef.current = null;
        isWatchingRef.current = false;
      }
    };
  }, []);

  return {
    getCurrentLocation,
    startWatchingLocation,
    stopWatchingLocation,
    isWatching
  };
};