/**
 * createModuleLoader - 创建模块加载器函数
 * 用于 React Navigation 的 getComponent API，实现真正的懒加载
 * 组件只在导航到该路由时才被创建和加载
 */

import React, { useEffect, useState } from 'react';
import { ModuleRegistry } from './ModuleRegistry';
import { ModuleLoadingPlaceholder } from './ModuleLoadingPlaceholder';
import { ModuleErrorFallback } from './ModuleErrorFallback';

type ModuleState = 'idle' | 'loading' | 'success' | 'error';

export interface ErrorFallbackProps {
  moduleId: string;
  error: Error | null;
  onRetry: () => void;
}

export interface CreateModuleLoaderOptions {
  onError?: (error: Error) => void;
  ErrorFallback?: React.ComponentType<ErrorFallbackProps>;
}

/**
 * 创建模块加载器函数
 * @param moduleId 模块 ID
 * @param pickComponent 从模块 exports 中提取组件的函数
 * @param options 可选配置
 * @returns 返回一个函数，该函数返回 React 组件（用于 getComponent）
 */
export function createModuleLoader(
  moduleId: string,
  pickComponent: (exports: any) => React.ComponentType<any>,
  options: CreateModuleLoaderOptions = {}
): () => React.ComponentType<any> {
  return function getModuleComponent() {
    function ModuleWrappedScreen(props: any) {
      const [state, setState] = useState<ModuleState>('idle');
      const [InnerComponent, setInnerComponent] =
        useState<React.ComponentType<any> | null>(null);
      const [error, setError] = useState<Error | null>(null);
      const [retryCount, setRetryCount] = useState(0);

      useEffect(() => {
        let isMounted = true;

        async function load() {
          try {
            setState('loading');

            await ModuleRegistry.loadModule(moduleId);
            if (!isMounted) return;

            const exports = ModuleRegistry.getModuleExports(moduleId);
            const Comp = pickComponent(exports);

            setInnerComponent(() => Comp);
            setState('success');
          } catch (e) {
            if (!isMounted) return;
            const err = e instanceof Error ? e : new Error(String(e));
            setError(err);
            setState('error');
            options.onError?.(err);
          }
        }

        load();

        return () => {
          isMounted = false;
        };
      }, [moduleId, retryCount]);

      if (state === 'error') {
        const FallbackComponent = options.ErrorFallback || ModuleErrorFallback;
        return (
          <FallbackComponent
            moduleId={moduleId}
            error={error}
            onRetry={() => {
              setState('idle');
              setError(null);
              setRetryCount((c) => c + 1);
            }}
          />
        );
      }

      if (state === 'loading' || !InnerComponent) {
        return <ModuleLoadingPlaceholder moduleId={moduleId} />;
      }

      return <InnerComponent {...props} />;
    }

    (ModuleWrappedScreen as any).displayName = `ModuleLoader(${moduleId})`;

    return ModuleWrappedScreen;
  };
}
