// File: src/services/Services.jsx
// Service boundary interface with dependency injection

import React, { createContext, useContext, useEffect, useMemo } from "react";

// ========================================
// SERVICE CLASS IMPORTS
// ========================================

// Core Services
import AuthManager from "./Manager/AuthManager.js";

// API Services
import ApiClient, { setApiClientAuthManager } from "./API/ApiClient.js";

// ========================================
// MODULE-LEVEL REFERENCE (for ApiClient)
// ========================================

// Store the latest AuthManager instance at module level
// This ensures ApiClient always uses the most recent instance
// even when React StrictMode creates multiple instances
let latestAuthManager = null;

// ========================================
// SERVICE CREATION & DEPENDENCY INJECTION
// ========================================

function createServices() {
  console.log(
    "[Services] 🚀 Creating service instances with dependency injection..."
  );

  // ========================================
  // 1. CORE SERVICES (No Dependencies)
  // ========================================

  const authManager = new AuthManager();
  console.log("[Services] ✓ AuthManager created");

  // Store this as the latest instance for ApiClient
  latestAuthManager = authManager;
  console.log("[Services] 📌 Latest AuthManager reference updated");

  // ========================================
  // 2. API CLIENT SETUP
  // ========================================

  // Pass a getter that returns the latest AuthManager instance
  // This handles React StrictMode creating multiple instances
  setApiClientAuthManager(() => latestAuthManager);
  console.log("[Services] ✓ ApiClient configured with AuthManager getter");

  // ========================================
  // 3. SERVICE REGISTRY
  // ========================================

  const services = {
    // Core services
    authManager,
    apiClient: ApiClient,
  };

  console.log(
    "[Services] ✅ Service registry created with",
    Object.keys(services).length,
    "services"
  );

  return services;
}

// ========================================
// REACT CONTEXT & PROVIDER
// ========================================

const ServiceContext = createContext();

export function ServiceProvider({ children }) {
  // useMemo ensures services are created only once, not on every render
  const services = useMemo(() => {
    console.log("[Services] 🔄 Creating services (should only happen once)");
    return createServices();
  }, []); // Empty dependency array = create only once

  // ========================================
  // SERVICE INITIALIZATION
  // ========================================

  useEffect(() => {
    const initializeServices = async () => {
      try {
        console.log("[Services] 🚀 Starting service initialization...");

        // CRITICAL: Update latestAuthManager to point to the services instance
        // This ensures ApiClient uses the same instance that gets initialized
        latestAuthManager = services.authManager;
        console.log("[Services] 🔗 Synced latestAuthManager with services.authManager");

        // Initialize AuthManager
        try {
          await services.authManager.initialize();
          console.log("[Services] ✓ AuthManager initialized");
        } catch (error) {
          console.warn(
            "[Services] ⚠️ AuthManager initialization failed:",
            error
          );
        }

        console.log("[Services] 🎉 All services initialized successfully!");
      } catch (error) {
        console.error(
          "[Services] ❌ Critical service initialization failure:",
          error
        );
      }
    };

    initializeServices();
  }, [services]);

  // ========================================
  // ERROR HANDLING
  // ========================================

  useEffect(() => {
    const handleUnhandledRejection = (event) => {
      console.error("[Services] 🚨 Unhandled promise rejection:", event.reason);
    };

    const handleError = (event) => {
      console.error("[Services] 🚨 Unhandled error:", event.error);
    };

    window.addEventListener("unhandledrejection", handleUnhandledRejection);
    window.addEventListener("error", handleError);

    return () => {
      window.removeEventListener(
        "unhandledrejection",
        handleUnhandledRejection
      );
      window.removeEventListener("error", handleError);
    };
  }, []);

  // ========================================
  // DEVELOPMENT DEBUG INFO
  // ========================================

  useEffect(() => {
    if (import.meta.env.DEV) {
      console.log("[Services] 🔧 Development mode - adding debug info");
      console.log("[Services] Available services:", Object.keys(services));
      console.log(
        "[Services] AuthManager authenticated:",
        services.authManager.isAuthenticated()
      );
      console.log(
        "[Services] 🏗️ Architecture: Single-file service boundary with full DI"
      );

      // Add services to window for debugging
      window.maplePressServices = services;
      console.log(
        "[Services] 🪟 Services available at window.maplePressServices for debugging"
      );
    }
  }, [services]);

  return (
    <ServiceContext.Provider value={services}>
      {children}
    </ServiceContext.Provider>
  );
}

// ========================================
// SERVICE HOOKS - BOUNDARY INTERFACE
// ========================================

/**
 * Main service hook - returns ALL services
 * This is your primary interface to the service layer
 */
export function useServices() {
  const context = useContext(ServiceContext);
  if (!context) {
    throw new Error("useServices must be used within a ServiceProvider");
  }
  return context;
}

/**
 * Authentication Services
 */
export function useAuth() {
  const { authManager } = useServices();
  return {
    authManager,
  };
}

/**
 * API Services
 */
export function useApi() {
  const { apiClient } = useServices();
  return {
    apiClient,
  };
}
