/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-empty */
// Copyright Epic Games, Inc. All Rights Reserved.

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

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);

  const [latencyTestResult, setLatencyTestResult] =
    useState<LatencyTestResults>();

  // Run on component mount:
  useEffect(() => {
    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 && onVideoInitialized();
      });

      streaming.addEventListener("latencyTestResult", (e) => {
        setLatencyTestResult(e.data.latencyTimings);
        // console.log("Data", e.data.latencyTimings);
      });

      setInterval(() => {
        streaming.requestLatencyTest();
      }, 500);

      // 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 {}
      };
    }
  }, []);

  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",
            color: "#fff",
          }}
          onClick={() => {
            pixelStreaming?.play();
            setClickToPlayVisible(false);
          }}
        >
          <div>Click to play</div>
        </div>
      )}

      <div className="absolute bottom-0 left-0 p-4 text-white text-xs bg-black">
        {latencyTestResult &&
          Object.entries(latencyTestResult).map(([key, value], i) => {
            if (
              [
                "EncodeMs",
                "CaptureToSendMs",
                "latencyExcludingDecode",
                "networkLatency",
                "testStartTimeMs",
              ].includes(key)
            )
              return (
                <div key={i}>
                  {key}: {value}
                </div>
              );
          })}
      </div>
    </div>
  );
};
