"use client";
import { useEffect, useState, useCallback, useRef } from "react";
import { io, ManagerOptions, Socket, SocketOptions } from "socket.io-client";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch, RootState } from "@/store/store";
import { useTranslations } from "next-intl";
import toast from "react-hot-toast";
import { CloseIcon, NotificationsIcon } from "@/assets/svgs/Icons";
import ImageWithFallback from "@/components/UiComponents/ImageWithFallback";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { setNotificationsModal } from "@/store/general";
import { setRefetch } from "@/store/Socket";

// prev https://multi-vendors-989.saied.aait-d.com:4053
// new https://pro-989-client.saied.aait-d.com:4072

const SOCKET_URL = "https://pro-989-client.saied.aait-d.com:4072";

const SOCKET_CONFIG: Partial<ManagerOptions & SocketOptions> = {
  withCredentials: true,
  transports: ["websocket"],
};

const NOTIFICATION_TYPES = ["buyer_return", "buyer_order", "order", "return"] as const;
const REFETCH_PAGES = ["orders", "returns", "received-orders"] as const;

type NotificationType = typeof NOTIFICATION_TYPES[number];

interface NotificationData {
  type: NotificationType | "chat" | "wallet";
  notifiable_id: string;
  title: string;
  body: string;
  icon?: string;
  params?: {
    name: string;
  };
}

interface ChatData {
  user: {
    full_name: string;
  };
}

const SocketHandler = () => {
  const searchParams = useSearchParams();
  const chat_id = searchParams.get("chat_id");
  const { id, full_name } = useSelector((state: RootState) => state.ProfileConfig);
  const [socket, setSocket] = useState<Socket | null>(null);
  const [audioPermissionGranted, setAudioPermissionGranted] = useState(false);
  const audioRef = useRef<HTMLAudioElement | null>(null);
  
  const t = useTranslations();
  const router = useRouter();
  const dispatch = useDispatch<AppDispatch>();
  const pathname = usePathname();

  // Initialize audio
  useEffect(() => {
    const audioFile = new URL("@/assets/sounds/notification.mp3", import.meta.url).href;
    audioRef.current = new Audio(audioFile);
  }, []);

  // Handle user interaction for audio permission
  useEffect(() => {
    const handleUserInteraction = () => {
      setAudioPermissionGranted(true);
    };

    const events = ['click', 'keydown', 'touchstart'];
    events.forEach(event => {
      document.addEventListener(event, handleUserInteraction, { once: true });
    });

    return () => {
      events.forEach(event => {
        document.removeEventListener(event, handleUserInteraction);
      });
    };
  }, []);

  const playNotificationSound = useCallback(() => {
    if (!audioPermissionGranted || !audioRef.current) return;
    
    audioRef.current.play().catch((err) => {
      console.warn("🔇 Unable to play sound:", err);
    });
  }, [audioPermissionGranted]);

  const handleNotificationClick = useCallback((notification: NotificationData, toastData: any) => {
    const routes = {
      chat: `/messages?chat_id=${notification.notifiable_id}`,
      wallet: `/account/wallet`,
      buyer_return: `/account/returns/${notification.notifiable_id}`,
      buyer_order: `/account/orders/${notification.notifiable_id}`,
      order: `/received-orders/${notification.notifiable_id}`,
      return: `/returns/${notification.notifiable_id}`,
    };

    if (routes[notification.type as keyof typeof routes]) {
      router.push(routes[notification.type as keyof typeof routes]);
    } else {
      dispatch(setNotificationsModal(true));
    }
    
    toast.dismiss(toastData.id);
  }, [router, dispatch]);

  const handleRefetchPages = useCallback((type: string) => {
    const isNotificationTypeMatch = NOTIFICATION_TYPES.includes(type as NotificationType);
    const isPageMatch = REFETCH_PAGES.some(page => pathname.includes(page));
    
    if (isNotificationTypeMatch && isPageMatch) {
      router.refresh();
      dispatch(setRefetch({ type, count: Math.random() * 100 }));
    }
  }, [pathname, router, dispatch]);

  const subscribeNotification = useCallback((notification: NotificationData) => {
    if (!notification) return;

    playNotificationSound();
    
    toast((data) => (
      <>
        <div
          onClick={() => handleNotificationClick(notification, data)}
          className="cursor-pointer flex items-center gap-4 lg:min-w-[300px]"
        >
          {notification?.icon ? (
            <ImageWithFallback
              src={notification.icon}
              width={100}
              height={100}
              alt={notification.title}
              className="size-10 rounded-full"
            />
          ) : (
            <NotificationsIcon className="bg-greynormal size-6 rounded-full p-1.5" />
          )}
          <div className="flex flex-col gap-1">
            <h5 className="text-text-gray font-semibold">
              {notification.type === "chat"
                  ? t("Text.received_msg", { name: notification?.params?.name || "" })
                  : notification?.title}
            </h5>
            <p className="mb-0 text-sm text-black font-medium line-clamp-1">
              {notification.body}
            </p>
          </div>
        </div>
        <span
          className="absolute p-1.5 top-3 left-3 z-10 cursor-pointer"
          onClick={() => toast.dismiss(data.id)}
        >
          <CloseIcon />
        </span>
      </>
    ));
    
    handleRefetchPages(notification.type);
  }, [playNotificationSound, handleNotificationClick, handleRefetchPages, t]);

  const handleChatMessage = useCallback((data: ChatData) => {
    if (data?.user?.full_name !== full_name) {
      playNotificationSound();
      router.refresh();
    }
  }, [full_name, playNotificationSound, router]);

  const handleNotificationMessage = useCallback((data: NotificationData) => {
    if (!pathname.includes("/messages")) {
      console.log("🚀 ~ socket.on ~ data:", data);
      subscribeNotification(data);
    }
    dispatch(setRefetch({ type: data.type, count: Math.random() * 100 }));
  }, [pathname, subscribeNotification, dispatch]);

  const cleanupSocket = useCallback((socketInstance: Socket) => {
    if (socketInstance) {
      socketInstance.removeAllListeners();
      socketInstance.disconnect();
      console.log("🛑 Socket disconnected and cleaned up");
    }
  }, []);

  // Socket connection management
  useEffect(() => {
    if (socket || !id) return;

    const newSocket = io(SOCKET_URL, SOCKET_CONFIG);

    newSocket.on("connect", () => {
      setSocket(newSocket);
      console.log("🔌 Socket connected:", newSocket.connected);
    });

    newSocket.on("connect_error", (err) => {
      console.error("❌ Socket connection error:", err.message);
      // Close socket on connection error
      cleanupSocket(newSocket);
      setSocket(null);
    });

    newSocket.on("disconnect", (reason) => {
      console.warn("⚠️ Socket disconnected:", reason);
      setSocket(null);
    });

    return () => {
      cleanupSocket(newSocket);
      setSocket(null);
    };
  }, [id, socket, cleanupSocket]);

  // Socket event listeners
  useEffect(() => {
    if (!socket || !id) return;

    // Chat message listener
    if (pathname.includes("/messages") && chat_id) {
      socket.on(`chat:${chat_id}`, handleChatMessage);
    }

    // Notification listener
    socket.on(`notification:${id}`, handleNotificationMessage);

    return () => {
      if (chat_id) {
        socket.off(`chat:${chat_id}`);
      }
      socket.off(`notification:${id}`);
    };
  }, [pathname, socket, chat_id, id, handleChatMessage, handleNotificationMessage]);

  return null;
};

export default SocketHandler;