"use client";

import { useEffect, useMemo } from "react";
import { toast } from "sonner";
import { usePathname } from "@/i18n/routing";
import { setRevalidate } from "@/app/actions/set-revalidate";
import { createEcho } from "@/lib/socket";
import { playNotificationSound } from "@/lib/toast-with-sound";
import { useAuth } from "@/contexts/auth-context";
import { applyRealtimeNotificationUpdate } from "@/hooks/use-notifications";
import { detectLocale } from "@/lib/locale";

type NotificationEventPayload = Record<string, unknown> | null;

const EXPLICIT_EVENTS = [
  ".notifications.changed",
  ".notification.created",
  "App\\Notifications\\Events\\BroadcastNotificationCreated",
  "Illuminate\\Notifications\\Events\\BroadcastNotificationCreated",
] as const;

const addLocalePrefix = (localePrefix: string, path: string) => {
  const normalizedPrefix = localePrefix === "/" ? "" : localePrefix;
  return `${normalizedPrefix}${path}`;
};

const toPayload = (value: unknown): NotificationEventPayload => {
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    return null;
  }

  return value as Record<string, unknown>;
};

const isNotificationEvent = (
  eventName: string,
  payload: NotificationEventPayload,
) => {
  if (/notification/i.test(eventName)) {
    return true;
  }

  if (!payload) {
    return false;
  }

  return Boolean(
    payload.notification ||
      payload.title ||
      payload.subject ||
      payload.message ||
      payload.msg ||
      payload.content ||
      payload.body ||
      (payload.data &&
        typeof payload.data === "object" &&
        !Array.isArray(payload.data) &&
        (Object.keys(payload.data).length > 0)),
  );
};

const normalizeEventName = (eventName: string) => {
  if (!eventName) return eventName;
  return eventName.startsWith(".") ? eventName : `.${eventName}`;
};

const shouldSkipFallbackEvent = (eventName: string) => {
  const normalized = normalizeEventName(eventName);
  return EXPLICIT_EVENTS.includes(normalized as (typeof EXPLICIT_EVENTS)[number]);
};

export function NotificationsSocketListener() {
  // Helper to extract toast title and description from payload
  const extractToastContent = (
    payload: NotificationEventPayload,
  ): { title: string; description?: string } => {
    if (!payload) return { title: "New notification" };
    const p = payload as Record<string, unknown>;
    const data = typeof p === "object" && p !== null && "data" in p
      ? (p["data"] as Record<string, unknown> | undefined)
      : undefined;

    const title = (p["title"] as string) ??
      (p["subject"] as string) ??
      (data?.["title"] as string) ??
      (data?.["subject"] as string) ??
      "New notification";

    const description = (p["description"] as string) ??
      (p["message"] as string) ??
      (p["msg"] as string) ??
      (p["content"] as string) ??
      (p["body"] as string) ??
      (data?.["description"] as string) ??
      (data?.["message"] as string) ??
      (data?.["msg"] as string) ??
      (data?.["content"] as string) ??
      (data?.["body"] as string);

    return { title, description };
  };
  const pathname = usePathname();
  const { user, isLoading } = useAuth();

  const localePrefix = useMemo(() => {
    const locale = detectLocale(pathname);
    return locale === "ar" ? "" : `/${locale}`;
  }, [pathname]);

  const channelName = user?.id ? `App.Models.User.${user.id}` : null;

  useEffect(() => {
    if (isLoading || !channelName) {
      return;
    }

    let echo: ReturnType<typeof createEcho> | null = null;

    const revalidateNotificationsPages = () => {
      void setRevalidate(addLocalePrefix(localePrefix, "/notifications"));
      if (pathname.includes("/notifications")) {
        void setRevalidate(pathname);
      }
    };

    const handleEvent = (eventName: string, eventData: unknown) => {
      const payload = toPayload(eventData);
      if (!isNotificationEvent(eventName, payload)) {
        return;
      }

      void applyRealtimeNotificationUpdate(eventName, payload);
      playNotificationSound();
      // Show toast notification for user feedback
      console.log(payload,"notification");
      
      const { title, description } = extractToastContent(payload);
      if (description) {
        toast.info(title, { description });

      } else {
        toast.info(title);
      }
      revalidateNotificationsPages();
    };

    try {
      echo = createEcho();
      const notificationsChannel = echo.private(channelName);

      EXPLICIT_EVENTS.forEach((eventName) => {
        notificationsChannel.listen(eventName, (eventData: unknown) => {
          handleEvent(eventName, eventData);
        });
      });

      notificationsChannel.listenToAll((eventName: string, eventData: unknown) => {
        if (shouldSkipFallbackEvent(eventName)) {
          return;
        }
        handleEvent(eventName, eventData);
      });
    } catch (error) {
      console.error("Error initializing notifications socket:", error);
    }

    return () => {
      if (echo) {
        echo.leave(channelName);
        echo.disconnect();
      }
    };
  }, [channelName, isLoading, localePrefix, pathname]);

  return null;
}
