import { useEffect, useState } from 'react';
import { DIContainer, container as globalContainer } from './DIContainer';

/**
 * Service container with React integration
 */
export class ServiceContainer extends DIContainer {
  private static instance: ServiceContainer;

  /**
   * Get singleton instance
   */
  static getInstance(): ServiceContainer {
    if (!ServiceContainer.instance) {
      ServiceContainer.instance = new ServiceContainer();
    }
    return ServiceContainer.instance;
  }

  /**
   * Initialize container with default services
   */
  async initialize(): Promise<void> {
    // Register core services here
    console.log('ServiceContainer initialized');
  }
}

/**
 * React hook to resolve services
 */
export function useService<T>(token: string): T | null {
  const [service, setService] = useState<T | null>(null);
  const [error, setError] = useState<Error | null>(null);

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

    const resolveService = async () => {
      try {
        const resolved = await globalContainer.resolve<T>(token);
        if (mounted) {
          setService(resolved);
          setError(null);
        }
      } catch (err) {
        if (mounted) {
          setError(err instanceof Error ? err : new Error('Unknown error'));
          setService(null);
        }
      }
    };

    resolveService();

    return () => {
      mounted = false;
    };
  }, [token]);

  if (error) {
    throw error;
  }

  return service;
}

/**
 * React hook to resolve services synchronously (for singletons)
 */
export function useServiceSync<T>(token: string): T {
  try {
    return globalContainer.resolveSync<T>(token);
  } catch (error) {
    throw new Error(`Service ${token} not available. Make sure it's registered as singleton and initialized.`);
  }
}

/**
 * React hook for service health monitoring
 */
export function useServiceHealth() {
  const [health, setHealth] = useState<Record<string, boolean>>({});
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const checkHealth = async () => {
      try {
        const healthStatus = await globalContainer.healthCheck();
        setHealth(healthStatus);
      } catch (error) {
        console.error('Health check failed:', error);
      } finally {
        setIsLoading(false);
      }
    };

    checkHealth();

    // Check health every 30 seconds
    const interval = setInterval(checkHealth, 30000);

    return () => clearInterval(interval);
  }, []);

  return { health, isLoading };
}

/**
 * Decorator for automatic service injection
 */
export function Injectable(token: string) {
  return function <T extends { new (...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
      constructor(...args: any[]) {
        super(...args);
        // Auto-register the service
        globalContainer.singleton(token, () => new constructor(...args));
      }
    };
  };
}

// Export global container
export { globalContainer as container };