/* eslint-disable react-hooks/exhaustive-deps */
// Copyright Epic Games, Inc. All Rights Reserved.

import { useEffect, useRef, useState } from "react";
import {
  Config,
  PixelStreaming,
} from "@epicgames-ps/lib-pixelstreamingfrontend-ue5.7";
import type { AllSettings } from "@epicgames-ps/lib-pixelstreamingfrontend-ue5.7";

export interface PixelStreamingWrapperProps {
  initialSettings?: Partial<AllSettings>;
  onVideoInitialized?: () => void;
}

export const PixelStreamingWrapper = ({
  initialSettings,
  onVideoInitialized,
}: PixelStreamingWrapperProps) => {
  // A reference to parent div element that the Pixel Streaming library attaches into:
  const videoParent = useRef<HTMLDivElement>(null);

  // Pixel streaming library instance is stored into this state variable after initialization:
  const [pixelStreaming, setPixelStreaming] = useState<PixelStreaming>();

  // A boolean state variable that determines if the Click to play overlay is shown:
  const [clickToPlayVisible, setClickToPlayVisible] = useState(false);

  // Run on component mount:
  useEffect(() => {
    // Сохраняем оригинальные методы console
    const originalLog = console.log;
    const originalInfo = console.info;
    const originalWarn = console.warn;

    // Переопределяем console для фильтрации логов Pixel Streaming
    console.log = (...args) => {
      const message = args[0]?.toString() || "";
      if (
        !message.includes("[Info]") &&
        !message.includes("[Debug]") &&
        !message.includes("Stack:")
      ) {
        originalLog.apply(console, args);
      }
    };

    console.info = (...args) => {
      const message = args[0]?.toString() || "";
      if (
        !message.includes("[Info]") &&
        !message.includes("[Debug]") &&
        !message.includes("Stack:")
      ) {
        originalInfo.apply(console, args);
      }
    };

    console.warn = (...args) => {
      const message = args[0]?.toString() || "";
      if (
        !message.includes("[Info]") &&
        !message.includes("[Debug]") &&
        !message.includes("Stack:")
      ) {
        originalWarn.apply(console, args);
      }
    };

    if (videoParent.current) {
      // Attach Pixel Streaming library to videoParent element:
      const config = new Config({ initialSettings });

      const streaming = new PixelStreaming(config, {
        videoElementParent: videoParent.current,
      });

      // register a playStreamRejected handler to show Click to play overlay if needed:
      streaming.addEventListener("playStreamRejected", () => {
        setClickToPlayVisible(true);
      });

      streaming.addEventListener("videoInitialized", () => {
        onVideoInitialized?.();
      });

      // Save the library instance into component state so that it can be accessed later:
      setPixelStreaming(streaming);

      // Clean up on component unmount:
      return () => {
        try {
          streaming.disconnect();
        } catch {
          //
        }

        // Восстанавливаем оригинальные методы console
        console.log = originalLog;
        console.info = originalInfo;
        console.warn = originalWarn;
      };
    }

    // Восстанавливаем console если компонент размонтируется до инициализации
    return () => {
      console.log = originalLog;
      console.info = originalInfo;
      console.warn = originalWarn;
    };
  }, []);

  return (
    <div
      style={{
        width: "100%",
        height: "100%",
        position: "relative",
      }}
    >
      <div
        style={{
          width: "100%",
          height: "100%",
        }}
        ref={videoParent}
      />
      {clickToPlayVisible && (
        <div
          style={{
            position: "absolute",
            top: 0,
            left: 0,
            width: "100%",
            height: "100%",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            cursor: "pointer",
          }}
          onClick={() => {
            pixelStreaming?.play();
            setClickToPlayVisible(false);
          }}
        >
          <div>Click to play</div>
        </div>
      )}
    </div>
  );
};
