import { AnimatePresence, motion } from "motion/react";
import { AlertCircle } from "lucide-react";

import { SidebarRelayConnectionCard } from "@/features/sidebar/ui/SidebarRelayConnectionCard";
import type { useSidebarRelayConnectionCard } from "@/features/sidebar/ui/useSidebarRelayConnectionCard";
import { cn } from "@/shared/lib/cn";
import { useIsMobile } from "@/shared/hooks/use-mobile";
import { useRelayConnection } from "@/shared/api/useRelayConnection";
import { useSidebar } from "@/shared/ui/sidebar";

type RelayConnectionOverlayProps = {
  card: ReturnType<typeof useSidebarRelayConnectionCard>;
  errorMessage?: string;
  hasCommunityRail?: boolean;
  isHuddleDrawerOpen?: boolean;
};

/**
 * Fixed bottom-left overlay that shows the relay reconnect card when the
 * sidebar is collapsed. When the sidebar is open, the card lives in the
 * sidebar footer instead (and this overlay is hidden). Offsets itself for
 * the community rail (48px) and huddle drawer when present.
 *
 * Also surfaces non-unreachable disconnect errors (e.g. auth rejections)
 * when the sidebar is hidden, since those errors are only rendered inside
 * the sidebar content area which is off-canvas when collapsed.
 */
export function RelayConnectionOverlay({
  card,
  errorMessage,
  hasCommunityRail,
  isHuddleDrawerOpen,
}: RelayConnectionOverlayProps) {
  const { open: sidebarOpen, openMobile } = useSidebar();
  const isMobile = useIsMobile();
  const connectionState = useRelayConnection();

  // Show the overlay when the sidebar surface isn't visible:
  // - Desktop: sidebar is collapsed (open === false)
  // - Mobile: the sheet is closed (openMobile === false)
  const isSidebarSurfaceHidden = isMobile ? !openMobile : !sidebarOpen;
  const shouldShowReconnectCard =
    card.showSidebarRelayConnectionCard && isSidebarSurfaceHidden;

  // Show a non-unreachable error (e.g. auth rejection) when the sidebar is
  // hidden and the reconnect card isn't already covering it.
  const hasNonUnreachableError =
    Boolean(errorMessage) &&
    !card.hasRelayUnreachableError &&
    connectionState === "disconnected";
  const shouldShowErrorFallback =
    hasNonUnreachableError &&
    isSidebarSurfaceHidden &&
    !shouldShowReconnectCard;

  return (
    <AnimatePresence>
      {shouldShowReconnectCard ? (
        <motion.div
          animate={{ opacity: 1, y: 0 }}
          className={cn(
            "pointer-events-none fixed z-50 w-[284px]",
            hasCommunityRail ? "left-[68px]" : "left-3",
            isHuddleDrawerOpen
              ? "bottom-[calc(var(--buzz-huddle-drawer-height,0px)+12px)]"
              : "bottom-3",
          )}
          exit={{ opacity: 0, y: 20 }}
          initial={{ opacity: 0, y: -20 }}
          key="relay-connection-overlay"
          transition={{ duration: 0.25, ease: [0.22, 1, 0.36, 1] }}
        >
          <div className="pointer-events-auto rounded-xl bg-background shadow-md">
            <SidebarRelayConnectionCard
              isConnected={card.isRelayConnectionSuccess}
              isReconnectPending={card.isRelayReconnectPending}
              isWaitingOnReconnectHook={card.isWaitingOnReconnectHook}
              onDismiss={card.onDismissRelayConnectionCard}
              onReconnect={card.onReconnectRelay}
            />
          </div>
        </motion.div>
      ) : null}
      {shouldShowErrorFallback ? (
        <motion.div
          animate={{ opacity: 1, y: 0 }}
          className={cn(
            "pointer-events-none fixed z-50 w-[284px]",
            hasCommunityRail ? "left-[68px]" : "left-3",
            isHuddleDrawerOpen
              ? "bottom-[calc(var(--buzz-huddle-drawer-height,0px)+12px)]"
              : "bottom-3",
          )}
          exit={{ opacity: 0, y: 20 }}
          initial={{ opacity: 0, y: -20 }}
          key="relay-error-overlay"
          transition={{ duration: 0.25, ease: [0.22, 1, 0.36, 1] }}
        >
          <div
            className="pointer-events-auto flex items-center gap-2 rounded-xl bg-background px-3 py-2.5 text-sm text-destructive shadow-md"
            data-testid="relay-error-overlay"
            role="alert"
          >
            <AlertCircle aria-hidden="true" className="h-4 w-4 shrink-0" />
            <span className="flex-1">{errorMessage}</span>
          </div>
        </motion.div>
      ) : null}
    </AnimatePresence>
  );
}
