import type { ModuleFederationRuntimePlugin } from "@module-federation/enhanced/runtime";
import type { ComponentType } from "react";
interface OfflineFallbackConfig {
  enableLogging?: boolean;
  fallbackTimeout?: number;
  retryAttempts?: number;
  retryDelay?: number;
  enableCircuitBreaker?: boolean;
  circuitBreakerThreshold?: number;
  circuitBreakerResetTimeout?: number;
  fallbackComponents?: Record<string, ComponentType>;
}
const enhancedOfflineFallbackPlugin = (
  config: OfflineFallbackConfig = {}
): ModuleFederationRuntimePlugin => {
  const {
    enableLogging = true,
    fallbackTimeout = 5000,
    retryAttempts = 2,
    retryDelay = 1000,
    enableCircuitBreaker = true,
    circuitBreakerThreshold = 3,
    circuitBreakerResetTimeout = 60000,
    fallbackComponents = {},
  } = config;
  const remoteStates = new Map<string, any>();
  const fallbackCache = new Map<string, ComponentType>();
  const log = (message: string, ...args: any[]) => {
    if (enableLogging) {
      console.warn(`[OfflineFallbackPlugin] ${message}`, ...args);
    }
  };
  const createFallbackComponent = (remoteId: string, error?: Error) => {
    if (fallbackComponents[remoteId]) {
      return fallbackComponents[remoteId];
    }
    const FallbackComponent = async () => {
      // Dynamically import React to avoid eager loading issues
      const React = await import('react');
      
      return React.createElement("div", {
        style: {
          padding: "16px",
          border: "2px dashed #ffa39e",
          borderRadius: "8px",
          backgroundColor: "#fff2f0",
          color: "#cf1322",
          textAlign: "center",
        },
      }, [
        React.createElement("h3", { key: "title" }, "Remote Module Unavailable"),
        React.createElement("p", { key: "description" }, 
          `The remote module "${remoteId}" is currently offline.`),
      ]);
    };
    return FallbackComponent;
  };
  return {
    name: "enhanced-offline-fallback-plugin",
    
    async errorLoadRemote(args) {
      const { id, error, lifecycle } = args;
      log(`Remote loading failed: ${id}`, { lifecycle, error: error?.message });
      switch (lifecycle) {
        case 'afterResolve':
          // Manifest loading failed
          return {
            id: 'fallback',
            name: 'fallback',
            metaData: {},
            shared: [],
            remotes: [],
            exposes: []
          };
        case 'onLoad':
          // Module loading failed
          return () => ({
            __esModule: true,
            default: createFallbackComponent(id, error),
          });
        default:
          return createFallbackComponent(id, error);
      }
    },
    onLoad(args) {
      log(`Successfully loaded remote: ${args.id}`);
      return args;
    },
  };
};
export default enhancedOfflineFallbackPlugin;