import { callAction } from "@agent-native/core/client/hooks";
import { useT } from "@agent-native/core/client/i18n";
import {
  isInAgentEmbed,
  postNavigate,
} from "@agent-native/core/client/navigation";
import { IconExternalLink } from "@tabler/icons-react";
import { useEffect, useState } from "react";
import { useSearchParams } from "react-router";

import SlideRenderer from "@/components/deck/SlideRenderer";
import type { Slide } from "@/context/DeckContext";
import messages from "@/i18n/en-US";
import type { AspectRatio } from "@/lib/aspect-ratios";

export function meta() {
  return [{ title: messages.raw.slidePreviewTitle }];
}

function SlideError({ message }: { message: string }) {
  const t = useT();
  return (
    <div className="flex h-screen w-screen items-center justify-center bg-black">
      <div className="text-center">
        <div className="text-sm font-medium text-white/60">
          {t("raw.slideUnavailable")}
        </div>
        <div className="mt-1 text-xs text-white/35">{message}</div>
      </div>
    </div>
  );
}

export default function SlideRoute() {
  const t = useT();
  const [params] = useSearchParams();
  const deckId = params.get("deckId");
  const slideNumberParam = params.get("slideNumber");
  const slideIndexParam = params.get("slideIndex");

  const [slide, setSlide] = useState<Slide | null>(null);
  const [aspectRatio, setAspectRatio] = useState<AspectRatio | undefined>(
    undefined,
  );
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  const slideNumber =
    slideNumberParam !== null ? parseInt(slideNumberParam, 10) : null;
  const slideIndex =
    slideNumber !== null
      ? slideNumber - 1
      : slideIndexParam !== null
        ? parseInt(slideIndexParam, 10)
        : 0;
  const inEmbed = isInAgentEmbed();

  useEffect(() => {
    if (!deckId) {
      setError("Missing deckId parameter.");
      setLoading(false);
      return;
    }
    if (
      slideNumberParam !== null &&
      (slideNumber === null || isNaN(slideNumber) || slideNumber < 1)
    ) {
      setError("slideNumber must be a positive 1-based number.");
      setLoading(false);
      return;
    }
    if (slideIndexParam !== null && isNaN(slideIndex)) {
      setError("slideIndex must be a number.");
      setLoading(false);
      return;
    }

    callAction<{ slides?: Slide[]; aspectRatio?: AspectRatio }>(
      "get-deck",
      { id: deckId },
      { method: "GET" },
    )
      .then((deck) => {
        const slides: Slide[] = deck.slides ?? [];
        if (slides.length === 0) {
          throw new Error("This deck has no slides.");
        }
        const idx = Math.max(0, Math.min(slideIndex, slides.length - 1));
        setSlide(slides[idx]);
        setAspectRatio(deck.aspectRatio);
        setLoading(false);
      })
      .catch((err: unknown) => {
        const status = (err as { status?: number } | undefined)?.status;
        if (status === 404) {
          setError("Deck not found.");
        } else if (status !== undefined) {
          setError(`Failed to load deck (HTTP ${status}).`);
        } else {
          setError(
            err instanceof Error ? err.message : t("raw.couldNotLoadSlide"),
          );
        }
        setLoading(false);
      });
  }, [deckId, slideIndex, slideIndexParam, slideNumber, slideNumberParam, t]);

  if (loading) {
    return <div className="h-screen w-screen bg-black" />;
  }

  if (error || !slide) {
    return <SlideError message={error ?? "Slide not found."} />;
  }

  function handleOpenInApp() {
    postNavigate(`/deck/${deckId}/present?slide=${slideIndex + 1}`);
  }

  return (
    <div className="relative h-screen w-screen overflow-hidden bg-black">
      <SlideRenderer
        slide={slide}
        thumbnail={false}
        aspectRatio={aspectRatio}
      />

      {inEmbed && (
        <button
          onClick={handleOpenInApp}
          className="absolute bottom-3 right-3 z-10 flex items-center gap-1.5 rounded-md bg-white/10 px-2.5 py-1.5 text-xs font-medium text-white/70 backdrop-blur-sm hover:bg-white/20 hover:text-white"
        >
          <IconExternalLink className="h-3.5 w-3.5" />
          {t("raw.openInApp")}
        </button>
      )}
    </div>
  );
}
