import { useState, useEffect, useCallback } from "react";
import { getToken, onMessage } from "firebase/messaging";
import { messaging } from "../../../app/firebase/firebase";
import useNotificationService from "./useNotificationService";
import { customizeToast } from "../../utils";

interface FCMNotification {
  title?: string;
  body?: string;
  icon?: string;
}

interface FCMData {
  [key: string]: string;
}

interface FCMPayload {
  notification?: FCMNotification;
  data?: FCMData;
}

function useFCM() {
  const [token, setToken] = useState<string | null>(null);
  const [notificationPermission, setNotificationPermission] =
    useState<NotificationPermission>("default");
  const [isSupported, setIsSupported] = useState(false);
  const [permissionChanged, setPermissionChanged] = useState(false);
  const { saveTokenAsync } = useNotificationService();

  // Load stored token from localStorage on mount
  useEffect(() => {
    const storedToken = localStorage.getItem("fcm-token");
    if (storedToken) {
      setToken(storedToken);
    }
  }, []);

  // Check if FCM is supported (only once on mount)
  useEffect(() => {
    if (
      typeof window !== "undefined" &&
      "serviceWorker" in navigator &&
      messaging
    ) {
      setIsSupported(true);
      setNotificationPermission(Notification.permission);
    }
  }, []);

  // Monitor permission changes (separate effect to avoid dependency issues)
  useEffect(() => {
    if (!isSupported) return;

    let lastKnownPermission = notificationPermission;

    const checkPermissionChanges = () => {
      const currentPermission = Notification.permission;
      if (currentPermission !== lastKnownPermission) {
        console.log(
          `Permission changed from ${lastKnownPermission} to ${currentPermission}`
        );

        setNotificationPermission(currentPermission);
        setPermissionChanged(true);

        // Trigger event to show popup again if permission was revoked
        if (currentPermission === "default" || currentPermission === "denied") {
          window.dispatchEvent(
            new CustomEvent("fcm-permission-changed", {
              detail: {
                oldPermission: lastKnownPermission,
                newPermission: currentPermission,
              },
            })
          );
        }

        lastKnownPermission = currentPermission;
      }
    };

    // Check every 3 seconds for permission changes (less frequent to reduce overhead)
    const interval = setInterval(checkPermissionChanges, 3000);

    return () => clearInterval(interval);
  }, [isSupported]); // Only depend on isSupported to avoid re-creating interval

  // Helper function to save token to localStorage and API
  const saveTokenToStorageAndAPI = useCallback(
    async (newToken: string) => {
      const storedToken = localStorage.getItem("fcm-token");
      const lastSavedTime = localStorage.getItem("fcm-token-saved-time");
      const now = Date.now();

      // Check if token is different or if it's been more than 24 hours since last save
      const isDifferentToken = storedToken !== newToken;
      const isStaleToken = lastSavedTime
        ? now - parseInt(lastSavedTime) > 24 * 60 * 60 * 1000
        : true;

      if (isDifferentToken || isStaleToken) {
        console.log(
          "🚀 Token is new or stale, calling API to save FCM token..."
        );
        console.log("Previous token:", storedToken);
        console.log("New token:", newToken);

        const result = await saveTokenAsync({ fcm_token: newToken });
        console.log("📡 API Response:", result);

        if (result.success) {
          // Store token and timestamp in localStorage
          localStorage.setItem("fcm-token", newToken);
          localStorage.setItem("fcm-token-saved-time", now.toString());
          return { success: true, wasSaved: true };
        } else {
          // FCM save failed (e.g. backend error) - fail silently; notifications are optional
          return { success: false, wasSaved: false };
        }
      } else {
        console.log("ℹ️ Token unchanged, skipping API call");
        return { success: true, wasSaved: false };
      }
    },
    [saveTokenAsync]
  );

  // Request notification permission and generate token (ONLY when user explicitly allows)
  const requestPermissionAndGenerateToken = useCallback(async () => {
    if (!isSupported) {
      return { success: false, token: null };
    }

    try {
      console.log("🔔 User explicitly requested permission - starting flow...");

      // Request permission
      const permission = await Notification.requestPermission();
      setNotificationPermission(permission);

      if (permission === "granted") {
        console.log("✅ Permission granted - generating token...");

        // Generate token immediately after permission is granted
        const vapidKey = process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY;
        if (!vapidKey) {
          console.error("VAPID key not found in environment variables");
          return { success: false, token: null };
        }

        const currentToken = await getToken(messaging, { vapidKey });

        if (currentToken) {
          setToken(currentToken);

          // Save token with deduplication logic
          const saveResult = await saveTokenToStorageAndAPI(currentToken);

          // if (saveResult.success) {
          //   if (saveResult.wasSaved) {
          //     customizeToast("Notifications enabled successfully", "success");
          //   } else {
          //     customizeToast("Notifications already enabled", "info");
          //   }
          // } else {
          //   customizeToast("Failed to save notification token", "danger");
          // }

          return { success: true, token: currentToken };
        } else {
          console.log("❌ No registration token available.");
          return { success: false, token: null };
        }
      } else {
        console.log("❌ Permission denied by user");
        // customizeToast("Notification permission denied", "warning");
        return { success: false, token: null };
      }
    } catch (error) {
      console.error("❌ Error in permission/token flow:", error);
      // customizeToast("Error enabling notifications", "danger");
      return { success: false, token: null };
    }
  }, [isSupported, saveTokenToStorageAndAPI]);

  // Setup foreground message listener
  const setupForegroundListener = useCallback(() => {
    if (!messaging) return;

    const unsubscribe = onMessage(messaging, (payload: FCMPayload) => {
      const notificationTitle =
        payload.notification?.title || "New Notification";
      const notificationBody =
        payload.notification?.body || "You have a new notification";

      // Show toast notification for foreground messages
      // customizeToast(`${notificationTitle}: ${notificationBody}`, "info");

      // Trigger custom event to update notification count
      window.dispatchEvent(
        new CustomEvent("fcm-notification-received", {
          detail: payload,
        })
      );
    });

    return unsubscribe;
  }, [messaging]);

  // Function to refresh token (can be called periodically or when app becomes active)
  const refreshToken = useCallback(async () => {
    if (!isSupported || !messaging || notificationPermission !== "granted") {
      return { success: false, token: null };
    }

    try {
      const vapidKey = process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY;
      if (!vapidKey) {
        console.error("VAPID key not found in environment variables");
        return { success: false, token: null };
      }

      const currentToken = await getToken(messaging, { vapidKey });

      if (currentToken) {
        setToken(currentToken);

        // Save token with deduplication logic
        const saveResult = await saveTokenToStorageAndAPI(currentToken);

        return {
          success: true,
          token: currentToken,
          wasSaved: saveResult.wasSaved,
        };
      } else {
        console.log("No registration token available during refresh");
        return { success: false, token: null };
      }
    } catch (error) {
      console.error("Error refreshing FCM token:", error);
      return { success: false, token: null };
    }
  }, [
    isSupported,
    messaging,
    notificationPermission,
    saveTokenToStorageAndAPI,
  ]);

  // Auto-refresh token when app becomes visible (optional)
  useEffect(() => {
    const handleVisibilityChange = () => {
      if (!document.hidden && notificationPermission === "granted") {
        // Refresh token when app becomes active, but only if permission is granted
        refreshToken();
      }
    };

    document.addEventListener("visibilitychange", handleVisibilityChange);

    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange);
    };
  }, [refreshToken, notificationPermission]);

  // Clear stored FCM data (useful when user logs out or revokes permission)
  const clearStoredFCMData = useCallback(() => {
    localStorage.removeItem("fcm-token");
    localStorage.removeItem("fcm-token-saved-time");
    localStorage.removeItem("fcm-user-interacted");
    setToken(null);
    console.log("🗑️ Cleared stored FCM data");
  }, []);

  // Reset permission changed flag
  const resetPermissionChanged = useCallback(() => {
    setPermissionChanged(false);
  }, []);

  return {
    token,
    notificationPermission,
    isSupported,
    permissionChanged,
    requestPermissionAndGenerateToken,
    refreshToken,
    clearStoredFCMData,
    setupForegroundListener,
    resetPermissionChanged,
  };
}

export default useFCM;
