import { baseUrl } from "@/api/baseUrl";
import useContextMenu from "@/hooks/use-contextmenu";
import { cn } from "@/lib/utils";
import {
  ClassificationItemData,
  ClassificationThreshold,
} from "@/types/classification";
import { Event } from "@/types/event";
import { useMemo, useRef, useState } from "react";
import { isDesktop, isMobile } from "react-device-detect";
import { useTranslation } from "react-i18next";
import TimeAgo from "../dynamic/TimeAgo";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import { LuSearch } from "react-icons/lu";
import { TooltipPortal } from "@radix-ui/react-tooltip";
import { useNavigate } from "react-router-dom";
import { getTranslatedLabel } from "@/utils/i18n";

type ClassificationCardProps = {
  imgClassName?: string;
  data: ClassificationItemData;
  threshold?: ClassificationThreshold;
  selected: boolean;
  i18nLibrary: string;
  showArea?: boolean;
  onClick: (data: ClassificationItemData, meta: boolean) => void;
  children?: React.ReactNode;
};
export function ClassificationCard({
  imgClassName,
  data,
  threshold,
  selected,
  i18nLibrary,
  showArea = true,
  onClick,
  children,
}: ClassificationCardProps) {
  const { t } = useTranslation([i18nLibrary]);
  const [imageLoaded, setImageLoaded] = useState(false);

  const scoreStatus = useMemo(() => {
    if (!data.score || !threshold) {
      return "unknown";
    }

    if (data.score >= threshold.recognition) {
      return "match";
    } else if (data.score >= threshold.unknown) {
      return "potential";
    } else {
      return "unknown";
    }
  }, [data, threshold]);

  // interaction

  const imgRef = useRef<HTMLImageElement | null>(null);

  useContextMenu(imgRef, () => {
    onClick(data, true);
  });

  const imageArea = useMemo(() => {
    if (!showArea || imgRef.current == null || !imageLoaded) {
      return undefined;
    }

    return imgRef.current.naturalWidth * imgRef.current.naturalHeight;
  }, [showArea, imageLoaded]);

  return (
    <div
      className={cn(
        "relative flex size-48 cursor-pointer flex-col overflow-hidden rounded-lg outline outline-[3px]",
        selected
          ? "shadow-selected outline-selected"
          : "outline-transparent duration-500",
      )}
    >
      <img
        ref={imgRef}
        className={cn(
          "absolute bottom-0 left-0 right-0 top-0 size-full",
          imgClassName,
          isMobile && "w-full",
        )}
        onLoad={() => setImageLoaded(true)}
        src={`${baseUrl}${data.filepath}`}
        onClick={(e) => {
          e.stopPropagation();
          onClick(data, e.metaKey || e.ctrlKey);
        }}
      />
      {false && imageArea != undefined && (
        <div className="absolute bottom-1 right-1 z-10 rounded-lg bg-black/50 px-2 py-1 text-xs text-white">
          {t("information.pixels", { ns: "common", area: imageArea })}
        </div>
      )}
      <div className="absolute bottom-0 left-0 right-0 h-[50%] bg-gradient-to-t from-black/60 to-transparent" />
      <div className="absolute bottom-0 flex w-full select-none flex-row items-center justify-between gap-2 p-2">
        <div
          className={cn(
            "flex flex-col items-start text-white",
            data.score ? "text-xs" : "text-sm",
          )}
        >
          <div className="smart-capitalize">
            {data.name == "unknown" ? t("details.unknown") : data.name}
          </div>
          {data.score && (
            <div
              className={cn(
                "",
                scoreStatus == "match" && "text-success",
                scoreStatus == "potential" && "text-orange-400",
                scoreStatus == "unknown" && "text-danger",
              )}
            >
              {Math.round(data.score * 100)}%
            </div>
          )}
        </div>
        <div className="flex flex-row items-start justify-end gap-5 md:gap-2">
          {children}
        </div>
      </div>
    </div>
  );
}

type GroupedClassificationCardProps = {
  group: ClassificationItemData[];
  event?: Event;
  threshold?: ClassificationThreshold;
  selectedItems: string[];
  i18nLibrary: string;
  objectType: string;
  onClick: (data: ClassificationItemData | undefined) => void;
  onSelectEvent: (event: Event) => void;
  children?: (data: ClassificationItemData) => React.ReactNode;
};
export function GroupedClassificationCard({
  group,
  event,
  threshold,
  selectedItems,
  i18nLibrary,
  objectType,
  onClick,
  onSelectEvent,
  children,
}: GroupedClassificationCardProps) {
  const navigate = useNavigate();
  const { t } = useTranslation(["views/explore", i18nLibrary]);

  // data

  const allItemsSelected = useMemo(
    () => group.every((data) => selectedItems.includes(data.filename)),
    [group, selectedItems],
  );

  const time = useMemo(() => {
    const item = group[0];

    if (!item?.timestamp) {
      return undefined;
    }

    return item.timestamp * 1000;
  }, [group]);

  return (
    <div
      className={cn(
        "flex cursor-pointer flex-col gap-2 rounded-lg bg-card p-2 outline outline-[3px]",
        isMobile && "w-full",
        allItemsSelected
          ? "shadow-selected outline-selected"
          : "outline-transparent duration-500",
      )}
      onClick={() => {
        if (selectedItems.length) {
          onClick(undefined);
        }
      }}
      onContextMenu={(e) => {
        e.stopPropagation();
        e.preventDefault();
        onClick(undefined);
      }}
    >
      <div className="flex flex-row justify-between">
        <div className="flex flex-col gap-1">
          <div className="select-none smart-capitalize">
            {getTranslatedLabel(objectType)}
            {event?.sub_label
              ? `: ${event.sub_label} (${Math.round((event.data.sub_label_score || 0) * 100)}%)`
              : ": " + t("details.unknown")}
          </div>
          {time && (
            <TimeAgo
              className="text-sm text-secondary-foreground"
              time={time}
              dense
            />
          )}
        </div>
        {event && (
          <Tooltip>
            <TooltipTrigger>
              <div
                className="cursor-pointer"
                onClick={() => {
                  navigate(`/explore?event_id=${event.id}`);
                }}
              >
                <LuSearch className="size-4 text-muted-foreground" />
              </div>
            </TooltipTrigger>
            <TooltipPortal>
              <TooltipContent>
                {t("details.item.button.viewInExplore", {
                  ns: "views/explore",
                })}
              </TooltipContent>
            </TooltipPortal>
          </Tooltip>
        )}
      </div>

      <div
        className={cn(
          "gap-2",
          isDesktop
            ? "flex flex-row flex-wrap"
            : "grid grid-cols-2 sm:grid-cols-5 lg:grid-cols-6",
        )}
      >
        {group.map((data: ClassificationItemData) => (
          <ClassificationCard
            key={data.filename}
            data={data}
            threshold={threshold}
            selected={
              allItemsSelected ? false : selectedItems.includes(data.filename)
            }
            i18nLibrary={i18nLibrary}
            onClick={(data, meta) => {
              if (meta || selectedItems.length > 0) {
                onClick(data);
              } else if (event) {
                onSelectEvent(event);
              }
            }}
          >
            {children?.(data)}
          </ClassificationCard>
        ))}
      </div>
    </div>
  );
}
