"use client";

import { useEffect } from "react";

/**
 * Component to handle ChunkLoadError automatically
 * When a chunk fails to load (usually after deployment), 
 * this component will force refresh the page once
 */
export default function ChunkLoadErrorHandler() {
  useEffect(() => {
    // Key to track if we've already refreshed for this error
    const REFRESH_KEY = "chunk-load-error-refreshed";
    const REFRESH_TIMESTAMP_KEY = "chunk-load-error-timestamp";
    
    // Flag to prevent multiple simultaneous refresh attempts
    let isRefreshing = false;

    /**
     * Check if error is actually a ChunkLoadError
     * This is more specific to avoid false positives
     */
    const isChunkLoadError = (error: any, message?: string): boolean => {
      // Direct ChunkLoadError check
      if (error?.name === "ChunkLoadError") return true;
      
      // Check for specific chunk loading patterns (for webpack/next.js)
      const errorMessage = error?.message || message || "";
      const isChunkError = 
        errorMessage.includes("Loading chunk") ||
        errorMessage.includes("ChunkLoadError") ||
        (errorMessage.includes("Failed to fetch") && errorMessage.includes("_next/static")) ||
        (errorMessage.includes("dynamically imported module") && errorMessage.includes("_next"));
      
      // Exclude normal network errors or API errors
      const isNotApiError = 
        !errorMessage.includes("/api/") &&
        !errorMessage.includes("http") &&
        !errorMessage.includes("https") &&
        !errorMessage.includes("service/") &&
        !errorMessage.includes("endpoint");
      
      return isChunkError && isNotApiError;
    };

    /**
     * Check if we should refresh based on time
     * Prevent refresh if last refresh was less than 5 seconds ago
     */
    const shouldRefresh = (): boolean => {
      const lastRefreshTime = sessionStorage.getItem(REFRESH_TIMESTAMP_KEY);
      if (!lastRefreshTime) return true;
      
      const timeSinceLastRefresh = Date.now() - parseInt(lastRefreshTime, 10);
      return timeSinceLastRefresh > 5000; // 5 seconds
    };

    // Handle unhandled promise rejections (for dynamic imports)
    const handlePromiseRejection = (event: PromiseRejectionEvent) => {
      const error = event.reason;
      
      // Only handle if it's actually a ChunkLoadError
      if (isChunkLoadError(error)) {
        console.warn("ChunkLoadError detected in promise rejection:", error);
        event.preventDefault(); // Prevent default error handling
        handleChunkLoadError();
      }
    };

    // Handle regular errors
    const handleError = (event: ErrorEvent) => {
      const error = event.error;
      
      // Only handle if it's actually a ChunkLoadError
      if (isChunkLoadError(error, event.message)) {
        console.warn("ChunkLoadError detected in error event:", error);
        event.preventDefault(); // Prevent default error handling
        handleChunkLoadError();
      }
    };

    const handleChunkLoadError = () => {
      // Prevent multiple simultaneous refresh attempts
      if (isRefreshing) {
        console.log("Refresh already in progress, skipping...");
        return;
      }

      // Check if we've already refreshed recently
      const hasRefreshed = sessionStorage.getItem(REFRESH_KEY);
      
      if (!hasRefreshed && shouldRefresh()) {
        isRefreshing = true;
        
        console.log("ChunkLoadError confirmed. Refreshing page in 100ms...");
        
        // Mark that we've refreshed
        sessionStorage.setItem(REFRESH_KEY, "true");
        sessionStorage.setItem(REFRESH_TIMESTAMP_KEY, Date.now().toString());
        
        // Small delay to allow logging and prevent immediate re-trigger
        setTimeout(() => {
          // Force reload the page (bypassing cache)
          window.location.reload();
        }, 100);
      } else if (hasRefreshed) {
        console.error("ChunkLoadError persists after refresh. There might be a deeper issue.");
        console.error("Please try clearing your browser cache or contact support.");
        
        // Clear the flag after 1 minute in case user navigates away and comes back
        setTimeout(() => {
          sessionStorage.removeItem(REFRESH_KEY);
          sessionStorage.removeItem(REFRESH_TIMESTAMP_KEY);
        }, 60000);
      }
    };

    // Clear old refresh flags on component mount (for new session)
    const clearOldFlags = () => {
      const lastRefreshTime = sessionStorage.getItem(REFRESH_TIMESTAMP_KEY);
      if (lastRefreshTime) {
        const timeSinceLastRefresh = Date.now() - parseInt(lastRefreshTime, 10);
        // Clear if last refresh was more than 5 minutes ago
        if (timeSinceLastRefresh > 300000) {
          sessionStorage.removeItem(REFRESH_KEY);
          sessionStorage.removeItem(REFRESH_TIMESTAMP_KEY);
        }
      }
    };

    clearOldFlags();

    // Add event listeners
    window.addEventListener("error", handleError, true); // Use capture phase
    window.addEventListener("unhandledrejection", handlePromiseRejection);

    // Cleanup event listeners
    return () => {
      window.removeEventListener("error", handleError, true);
      window.removeEventListener("unhandledrejection", handlePromiseRejection);
    };
  }, []);

  // This component doesn't render anything
  return null;
}

