// File: src/services/Services.jsx
// Complete single-file service boundary interface - TOTAL REPLACEMENT
//
// ⚠️ IMPORTANT - LINTER WARNINGS:
// This file has intentional patterns that may trigger ESLint warnings:
// 1. Empty dependency arrays in some useCallback/useMemo - these are INTENTIONAL to prevent infinite loops
// 2. useMemo dependencies on [services] - this is STABLE and correct
// 3. DO NOT auto-fix exhaustive-deps warnings without understanding the infinite loop implications
//
// If you see warnings about missing dependencies, DO NOT blindly add them.
// Adding service dependencies to callbacks will cause infinite re-render loops.
// We use refs and memoization strategically to maintain stability.

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

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

// Core Services
import AuthManager from "./Manager/AuthManager.js";
import MeManager from "./Manager/MeManager.js";
import TokenManager from "./Manager/TokenManager.js";
import RecoveryManager from "./Manager/RecoveryManager.js";

// Crypto Services
import CryptoService from "./Crypto/CryptoService.js";
import CollectionCryptoService from "./Crypto/CollectionCryptoService.js";
import TagCryptoService from "./Crypto/TagCryptoService.js";

// Storage Services
import LocalStorageService from "./Storage/LocalStorageService.js";
import passwordStorageService from "./PasswordStorageService.js";

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

// Collection Services
import SyncCollectionAPIService from "./API/SyncCollectionAPIService.js";
import SyncCollectionStorageService from "./Storage/SyncCollectionStorageService.js";
import SyncCollectionManager from "./Manager/SyncCollectionManager.js";
import CreateCollectionManager from "./Manager/Collection/CreateCollectionManager.js";
import GetCollectionManager from "./Manager/Collection/GetCollectionManager.js";
import UpdateCollectionManager from "./Manager/Collection/UpdateCollectionManager.js";
import DeleteCollectionManager from "./Manager/Collection/DeleteCollectionManager.js";
import ListCollectionManager from "./Manager/Collection/ListCollectionManager.js";
import ShareCollectionManager from "./Manager/Collection/ShareCollectionManager.js";

// File Services
import SyncFileAPIService from "./API/SyncFileAPIService.js";
import SyncFileStorageService from "./Storage/SyncFileStorageService.js";
import SyncFileManager from "./Manager/SyncFileManager.js";
import CreateFileManager from "./Manager/File/CreateFileManager.js";
import GetFileManager from "./Manager/File/GetFileManager.js";
import ListFileManager from "./Manager/File/ListFileManager.js";
import DownloadFileManager from "./Manager/File/DownloadFileManager.js";
import DeleteFileManager from "./Manager/File/DeleteFileManager.js";

// User Services
import UserLookupManager from "./Manager/User/UserLookupManager.js";

// Dashboard Services
import DashboardManager from "./Manager/DashboardManager.js";

// Tag Services
import TagManager from "./Manager/Tag/TagManager.js";
import CollectionTagManager from "./Manager/Collection/CollectionTagManager.js";
import FileTagManager from "./Manager/File/FileTagManager.js";

// ========================================
// 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");

  // ========================================
  // 2. AUTH-DEPENDENT SERVICES
  // ========================================

  const meManager = new MeManager(authManager);
  const tokenManager = new TokenManager(authManager);
  const recoveryManager = new RecoveryManager();
  console.log("[Services] ✓ Auth-dependent managers created");

  // ========================================
  // 3. USER SERVICES
  // ========================================

  const userLookupManager = new UserLookupManager(authManager);
  console.log("[Services] ✓ User services created");

  // ========================================
  // 4. COLLECTION SERVICES
  // ========================================

  const syncCollectionAPIService = new SyncCollectionAPIService(authManager);
  const syncCollectionStorageService = new SyncCollectionStorageService();
  const syncCollectionManager = new SyncCollectionManager(authManager);
  const createCollectionManager = new CreateCollectionManager(authManager);
  const getCollectionManager = new GetCollectionManager(authManager);
  const updateCollectionManager = new UpdateCollectionManager(authManager);
  const deleteCollectionManager = new DeleteCollectionManager(authManager);
  const listCollectionManager = new ListCollectionManager(authManager);
  const shareCollectionManager = new ShareCollectionManager(
    authManager,
    userLookupManager,
  );
  console.log("[Services] ✓ Collection services created");

  // ========================================
  // 5. FILE SERVICES (Complex Dependencies)
  // ========================================

  const syncFileAPIService = new SyncFileAPIService(authManager);
  const syncFileStorageService = new SyncFileStorageService();
  const syncFileManager = new SyncFileManager(authManager);
  const createFileManager = new CreateFileManager(authManager);

  // File services with collection dependencies
  const getFileManager = new GetFileManager(
    authManager,
    getCollectionManager,
    listCollectionManager,
  );

  const listFileManager = new ListFileManager(
    authManager,
    getCollectionManager,
    listCollectionManager,
  );

  const downloadFileManager = new DownloadFileManager(
    authManager,
    getFileManager,
    getCollectionManager,
  );

  const deleteFileManager = new DeleteFileManager(
    authManager,
    getCollectionManager,
    listCollectionManager,
  );
  console.log("[Services] ✓ File services created with dependencies");

  // ========================================
  // 6. API CLIENT SETUP
  // ========================================

  setApiClientAuthManager(authManager);
  console.log("[Services] ✓ ApiClient configured with AuthManager");

  // ========================================
  // 7. Dashboard Services
  // ========================================

  const dashboardManager = new DashboardManager(authManager);
  console.log("[Services] ✓ Dashboard manager created");

  // ========================================
  // 8. Tag Services
  // ========================================

  const tagManager = new TagManager(authManager);
  const collectionTagManager = new CollectionTagManager(
    authManager,
    getCollectionManager,
    listCollectionManager,
  );
  const fileTagManager = new FileTagManager(
    authManager,
    getFileManager,
    listFileManager,
  );
  console.log("[Services] ✓ Tag managers created");

  // ========================================
  // 9. MANAGER CROSS-REFERENCES (For Cache Invalidation)
  // ========================================

  // Set up cross-references for cache invalidation
  createCollectionManager.setListCollectionManager(listCollectionManager);
  console.log("[Services] ✓ Manager cross-references configured");

  // ========================================
  // 9. SERVICE REGISTRY
  // ========================================

  const services = {
    // Core services (singletons)
    authManager,
    authService: authManager, // Backward compatibility alias
    cryptoService: CryptoService,
    CollectionCryptoService,
    passwordStorageService,
    localStorageService: LocalStorageService,
    apiClient: ApiClient,

    // Auth & User Management
    meManager,
    meService: meManager, // Backward compatibility alias
    tokenManager,
    tokenService: tokenManager, // Backward compatibility alias
    recoveryManager,

    // Collection Services
    syncCollectionAPIService,
    syncCollectionStorageService,
    syncCollectionManager,
    createCollectionManager,
    getCollectionManager,
    updateCollectionManager,
    deleteCollectionManager,
    listCollectionManager,
    shareCollectionManager,

    // File Services
    createFileManager,
    getFileManager,
    listFileManager,
    downloadFileManager,
    deleteFileManager,
    syncFileAPIService,
    syncFileStorageService,
    syncFileManager,

    // User Services
    userLookupManager,

    // Dashboard Services
    dashboardManager,

    // Tag Services
    tagManager,
    collectionTagManager,
    fileTagManager,
  };

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

  return services;
}

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

const ServiceContext = createContext();

// Module-level singleton to prevent duplicate service creation across StrictMode remounts
let servicesInstance = null;
let initializationPromise = null;

export function ServiceProvider({ children }) {
  // Create services only once using module-level singleton
  // This prevents duplicate creation even when React StrictMode remounts the component
  const services = useMemo(() => {
    if (!servicesInstance) {
      console.log("[ServiceProvider] Creating services (first and only time)");
      servicesInstance = createServices();
    } else {
      if (import.meta.env.DEV) {
        console.log(
          "[ServiceProvider] Reusing existing services instance (StrictMode remount)",
        );
      }
    }
    return servicesInstance;
  }, []); // Empty dependency array = create only once per component instance

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

  useEffect(() => {
    const initializeServices = async () => {
      // If already initializing or initialized, skip
      if (initializationPromise) {
        if (import.meta.env.DEV) {
          console.log(
            "[Services] ⏭️ Initialization already in progress or complete, skipping...",
          );
        }
        return initializationPromise;
      }

      // Create initialization promise to prevent duplicate initialization
      initializationPromise = (async () => {
        try {
          console.log("[Services] 🚀 Starting service initialization...");

          // ========================================
          // 1. CORE CRYPTO & STORAGE SERVICES
          // ========================================

          await CryptoService.initialize();
          console.log("[Services] ✓ CryptoService initialized");

          await CollectionCryptoService.initialize();
          console.log("[Services] ✓ CollectionCryptoService initialized");

          try {
            await passwordStorageService.initialize();
            console.log("[Services] ✓ PasswordStorageService initialized");
          } catch (error) {
            console.warn(
              "[Services] ⚠️ PasswordStorageService initialization failed:",
              error,
            );
          }

          // ========================================
          // 2. AUTH MANAGER
          // ========================================

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

          // ========================================
          // 3. MANAGER INITIALIZATION
          // ========================================

          const managersToInitialize = [
            { manager: services.dashboardManager, name: "DashboardManager" },
            { manager: services.meManager, name: "MeManager" },
            { manager: services.tokenManager, name: "TokenManager" },
            { manager: services.recoveryManager, name: "RecoveryManager" },
            { manager: services.tagManager, name: "TagManager" },
            {
              manager: services.syncCollectionManager,
              name: "SyncCollectionManager",
            },
            {
              manager: services.createCollectionManager,
              name: "CreateCollectionManager",
            },
            {
              manager: services.getCollectionManager,
              name: "GetCollectionManager",
            },
            {
              manager: services.updateCollectionManager,
              name: "UpdateCollectionManager",
            },
            {
              manager: services.deleteCollectionManager,
              name: "DeleteCollectionManager",
            },
            {
              manager: services.listCollectionManager,
              name: "ListCollectionManager",
            },
            {
              manager: services.shareCollectionManager,
              name: "ShareCollectionManager",
            },
            { manager: services.createFileManager, name: "CreateFileManager" },
            { manager: services.getFileManager, name: "GetFileManager" },
            { manager: services.listFileManager, name: "ListFileManager" },
            {
              manager: services.downloadFileManager,
              name: "DownloadFileManager",
            },
            { manager: services.deleteFileManager, name: "DeleteFileManager" },
            { manager: services.syncFileManager, name: "SyncFileManager" },
            { manager: services.userLookupManager, name: "UserLookupManager" },
          ];

          for (const { manager, name } of managersToInitialize) {
            try {
              await manager.initialize();
              console.log(`[Services] ✓ ${name} initialized`);
            } catch (error) {
              console.warn(
                `[Services] ⚠️ ${name} initialization failed:`,
                error,
              );
            }
          }

          console.log("[Services] 🎉 All services initialized successfully!");
        } catch (error) {
          console.error(
            "[Services] ❌ Critical service initialization failure:",
            error,
          );
          // Reset promise on failure to allow retry
          initializationPromise = null;
          throw error;
        }
      })();

      return initializationPromise;
    };

    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] CryptoService ready:",
        CryptoService.isInitialized,
      );
      console.log(
        "[Services] CollectionCryptoService ready:",
        CollectionCryptoService.isReady(),
      );
      console.log(
        "[Services] PasswordStorageService ready:",
        passwordStorageService.isInitialized,
      );
      console.log(
        "[Services] AuthManager authenticated:",
        services.authManager.isAuthenticated(),
      );
      console.log(
        "[Services] UserLookupManager ready:",
        services.userLookupManager ? "✅" : "❌",
      );
      console.log(
        "[Services] 🏗️ Architecture: Single-file service boundary with full DI",
      );

      // Add services to window for debugging
      window.mapleopentechServices = services;
      console.log(
        "[Services] 🪟 Services available at window.mapleopentechServices 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 & User Management Services
 * 🔧 MEMOIZED: Returns stable object reference to prevent infinite loops
 */
export function useAuth() {
  const services = useServices();

  return useMemo(
    () => ({
      authManager: services.authManager,
      authService: services.authService,
      meManager: services.meManager,
      meService: services.meService,
      tokenManager: services.tokenManager,
      tokenService: services.tokenService,
      recoveryManager: services.recoveryManager,
    }),
    [services],
  );
}

/**
 * Collection Management Services
 * 🔧 MEMOIZED: Returns stable object reference to prevent infinite loops
 */
export function useCollections() {
  const services = useServices();

  return useMemo(
    () => ({
      syncCollectionAPIService: services.syncCollectionAPIService,
      syncCollectionStorageService: services.syncCollectionStorageService,
      syncCollectionManager: services.syncCollectionManager,
      createCollectionManager: services.createCollectionManager,
      getCollectionManager: services.getCollectionManager,
      updateCollectionManager: services.updateCollectionManager,
      deleteCollectionManager: services.deleteCollectionManager,
      listCollectionManager: services.listCollectionManager,
      shareCollectionManager: services.shareCollectionManager,
    }),
    [services],
  );
}

/**
 * File Management Services
 * 🔧 FIXED: Now includes auth and collection dependencies that file managers need
 * 🔧 MEMOIZED: Returns stable object reference to prevent infinite loops
 */
export function useFiles() {
  const services = useServices();

  // Memoize the return object to prevent infinite re-renders
  // Only recreate if services context changes (which should be never after init)
  return useMemo(
    () => ({
      // File services
      syncFileAPIService: services.syncFileAPIService,
      syncFileStorageService: services.syncFileStorageService,
      syncFileManager: services.syncFileManager,
      createFileManager: services.createFileManager,
      getFileManager: services.getFileManager,
      listFileManager: services.listFileManager,
      downloadFileManager: services.downloadFileManager,
      deleteFileManager: services.deleteFileManager,

      // Dependencies that file managers need
      authService: services.authManager,
      authManager: services.authManager,
      getCollectionManager: services.getCollectionManager,
      listCollectionManager: services.listCollectionManager,
      deleteCollectionManager: services.deleteCollectionManager,
    }),
    [services],
  );
}

/**
 * Cryptography Services
 * 🔧 MEMOIZED: Returns stable object reference to prevent infinite loops
 */
export function useCrypto() {
  const services = useServices();

  return useMemo(
    () => ({
      cryptoService: services.cryptoService,
      CollectionCryptoService: services.CollectionCryptoService,
    }),
    [services],
  );
}

/**
 * Storage Services
 */
export function useStorage() {
  const { localStorageService, passwordStorageService } = useServices();
  return {
    localStorageService,
    passwordStorageService,
  };
}

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

/**
 * User Services
 */
export function useUsers() {
  const { userLookupManager } = useServices();
  return {
    userLookupManager,
  };
}

/**
 * Dashboard Services
 */
export function useDashboard() {
  const { dashboardManager } = useServices();
  return {
    dashboardManager,
  };
}

/**
 * Tag Services
 */
export function useTags() {
  const { tagManager, collectionTagManager, fileTagManager } = useServices();
  return {
    tagManager,
    collectionTagManager,
    fileTagManager,
  };
}
