import TimeAgo from "../dynamic/TimeAgo";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import { useCallback, useEffect, useMemo, useState } from "react";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
import { REVIEW_PADDING, ReviewSegment } from "@/types/review";
import { useNavigate } from "react-router-dom";
import { RecordingStartingPoint } from "@/types/record";
import axios from "axios";
import { isCurrentHour } from "@/utils/dateUtil";
import { useCameraPreviews } from "@/hooks/use-camera-previews";
import { baseUrl } from "@/api/baseUrl";
import { VideoPreview } from "../preview/ScrubbablePreview";
import { useApiHost } from "@/api";
import { isDesktop, isSafari } from "react-device-detect";
import { usePersistence } from "@/hooks/use-persistence";
import { Skeleton } from "../ui/skeleton";
import { Button } from "../ui/button";
import { FaCircleCheck } from "react-icons/fa6";

type AnimatedEventCardProps = {
  event: ReviewSegment;
  selectedGroup?: string;
  updateEvents: () => void;
};
export function AnimatedEventCard({
  event,
  selectedGroup,
  updateEvents,
}: AnimatedEventCardProps) {
  const { data: config } = useSWR<FrigateConfig>("config");
  const apiHost = useApiHost();

  const currentHour = useMemo(() => isCurrentHour(event.start_time), [event]);

  const initialTimeRange = useMemo(() => {
    return {
      after: Math.round(event.start_time),
      before: Math.round(event.end_time || event.start_time + 20),
    };
  }, [event]);

  // preview

  const previews = useCameraPreviews(initialTimeRange, {
    camera: event.camera,
    fetchPreviews: !currentHour,
  });

  // visibility

  const [windowVisible, setWindowVisible] = useState(true);
  const visibilityListener = useCallback(() => {
    setWindowVisible(document.visibilityState == "visible");
  }, []);

  useEffect(() => {
    addEventListener("visibilitychange", visibilityListener);

    return () => {
      removeEventListener("visibilitychange", visibilityListener);
    };
  }, [visibilityListener]);

  const [isLoaded, setIsLoaded] = useState(false);
  const [isHovered, setIsHovered] = useState(false);

  // interaction

  const navigate = useNavigate();
  const onOpenReview = useCallback(() => {
    const url =
      selectedGroup && selectedGroup != "default"
        ? `review?group=${selectedGroup}`
        : "review";
    navigate(url, {
      state: {
        severity: event.severity,
        recording: {
          camera: event.camera,
          startTime: event.start_time - REVIEW_PADDING,
          severity: event.severity,
        } as RecordingStartingPoint,
      },
    });
    axios.post(`reviews/viewed`, { ids: [event.id] });
  }, [navigate, selectedGroup, event]);

  // image behavior

  const [alertVideos] = usePersistence("alertVideos", true);

  const aspectRatio = useMemo(() => {
    if (
      !config ||
      !alertVideos ||
      !Object.keys(config.cameras).includes(event.camera)
    ) {
      return 16 / 9;
    }

    const detect = config.cameras[event.camera].detect;
    return detect.width / detect.height;
  }, [alertVideos, config, event]);

  return (
    <Tooltip>
      <TooltipTrigger asChild>
        <div
          className="relative h-24 4k:h-32"
          style={{
            aspectRatio: aspectRatio,
          }}
          onMouseEnter={isDesktop ? () => setIsHovered(true) : undefined}
          onMouseLeave={isDesktop ? () => setIsHovered(false) : undefined}
        >
          {isHovered && (
            <Tooltip>
              <TooltipTrigger asChild>
                <Button
                  className="absolute right-2 top-1 z-40 bg-gray-500 bg-gradient-to-br from-gray-400 to-gray-500"
                  size="xs"
                  onClick={async () => {
                    await axios.post(`reviews/viewed`, { ids: [event.id] });
                    updateEvents();
                  }}
                >
                  <FaCircleCheck className="size-3 text-white" />
                </Button>
              </TooltipTrigger>
              <TooltipContent>Mark as Reviewed</TooltipContent>
            </Tooltip>
          )}
          {previews != undefined && (
            <div
              className="size-full cursor-pointer overflow-hidden rounded md:rounded-lg"
              onClick={onOpenReview}
              onAuxClick={() =>
                window
                  .open(`${baseUrl}review?id=${event.id}`, "_blank")
                  ?.focus()
              }
            >
              {!alertVideos ? (
                <img
                  className="size-full select-none"
                  src={`${apiHost}${event.thumb_path.replace("/media/frigate/", "")}`}
                  loading={isSafari ? "eager" : "lazy"}
                  onLoad={() => setIsLoaded(true)}
                />
              ) : (
                <>
                  {previews.length ? (
                    <VideoPreview
                      relevantPreview={previews[previews.length - 1]}
                      startTime={event.start_time}
                      endTime={event.end_time}
                      loop
                      showProgress={false}
                      setReviewed={() => {}}
                      setIgnoreClick={() => {}}
                      isPlayingBack={() => {}}
                      onTimeUpdate={() => {
                        if (!isLoaded) {
                          setIsLoaded(true);
                        }
                      }}
                      windowVisible={windowVisible}
                    />
                  ) : (
                    <video
                      preload="auto"
                      autoPlay
                      playsInline
                      muted
                      disableRemotePlayback
                      loop
                      onTimeUpdate={() => {
                        if (!isLoaded) {
                          setIsLoaded(true);
                        }
                      }}
                    >
                      <source
                        src={`${baseUrl}api/review/${event.id}/preview?format=mp4`}
                        type="video/mp4"
                      />
                    </video>
                  )}
                </>
              )}
            </div>
          )}
          {isLoaded && (
            <div className="absolute inset-x-0 bottom-0 h-6 rounded bg-gradient-to-t from-slate-900/50 to-transparent">
              <div className="absolute bottom-0 left-1 w-full text-xs text-white">
                <TimeAgo time={event.start_time * 1000} dense />
              </div>
            </div>
          )}
          {!isLoaded && <Skeleton className="absolute inset-0" />}
        </div>
      </TooltipTrigger>
      <TooltipContent>
        {`${[
          ...new Set([
            ...(event.data.objects || []),
            ...(event.data.sub_labels || []),
            ...(event.data.audio || []),
          ]),
        ]
          .filter((item) => item !== undefined && !item.includes("-verified"))
          .map((text) => text.charAt(0).toUpperCase() + text.substring(1))
          .sort()
          .join(", ")
          .replaceAll("-verified", "")} detected`}
      </TooltipContent>
    </Tooltip>
  );
}
