import { useRef } from "react";
import { Link, useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { FiArrowLeft } from "react-icons/fi";
import { useApiSocialPostsRetrieve } from "@/api/generated/private/posts/posts";
import Post from "@/components/social/posts/Post";
import PostComposer from "@/components/social/posts/PostComposer";
import Spinner from "@/components/ui/Spinner";
import EmptyState from "@/components/ui/EmptyState";
import { useInfiniteReplies } from "@/hooks/useInfinitePosts";
import { useIntersectionLoader } from "@/hooks/useIntersectionLoader";

const MAX_PARENT_DEPTH = 5;

interface ParentChainProps {
  parentId: number;
  depth: number;
}

function ParentChainItem({ parentId, depth }: ParentChainProps) {
  const { data: parent, isLoading } = useApiSocialPostsRetrieve(parentId);
  if (isLoading || !parent) return null;
  return (
    <>
      {parent.reply_to && depth < MAX_PARENT_DEPTH && (
        <ParentChainItem parentId={parent.reply_to} depth={depth + 1} />
      )}
      <Link to={`/social/post/${parent.id}`} className="block">
        <Post post={parent} variant="compact" clickable={false} />
      </Link>
    </>
  );
}

export default function PostPage() {
  const { t } = useTranslation("social");
  const { id } = useParams<{ id: string }>();
  const postId = Number(id);

  const composerRef = useRef<HTMLDivElement>(null);

  function focusComposer() {
    composerRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
    composerRef.current?.querySelector("textarea")?.focus({ preventScroll: true });
  }

  const { data: post, isLoading, isError } = useApiSocialPostsRetrieve(postId);
  const {
    replies,
    isLoading: repliesLoading,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteReplies({ postId, enabled: !!postId });

  const sentinelRef = useIntersectionLoader<HTMLDivElement>(
    () => {
      if (hasNextPage && !isFetchingNextPage) void fetchNextPage();
    },
    { enabled: hasNextPage },
  );

  if (isLoading) {
    return (
      <div className="flex justify-center py-10">
        <Spinner size={28} />
      </div>
    );
  }

  if (isError || !post) {
    return <EmptyState title={t("post.notFound")} />;
  }

  return (
    <div>
      <header className="sticky top-0 z-10 flex items-center gap-3 border-b border-brand-lines/10 bg-brand-bg/80 px-4 py-3 backdrop-blur">
        <Link
          to="/social/feed"
          className="rounded-full p-1 text-brand-text hover:bg-brand-lines/10"
          aria-label={t("post.detail.back")}
        >
          <FiArrowLeft size={20} />
        </Link>
        <h1 className="text-lg font-bold text-brand-text">{t("post.detail.back")}</h1>
      </header>

      {post.reply_to != null && (
        <div className="border-b border-brand-lines/10">
          <ParentChainItem parentId={post.reply_to} depth={0} />
        </div>
      )}

      <Post post={post} variant="focused" clickable={false} onReplyClick={focusComposer} />

      <div ref={composerRef}>
        <PostComposer parentId={post.id} hubId={post.hub ?? null} />
      </div>

      <section>
        {repliesLoading && (
          <div className="flex justify-center py-6">
            <Spinner size={24} />
          </div>
        )}

        {!repliesLoading && replies.length === 0 && (
          <EmptyState message={t("post.thread.noReplies")} />
        )}

        {replies.map((r) => (
          <Post key={r.id} post={r} />
        ))}

        {hasNextPage && (
          <div
            ref={sentinelRef}
            className="flex items-center justify-center py-4 text-sm text-brand-text/60"
          >
            {isFetchingNextPage ? <Spinner size={20} /> : t("feed.loadingMore")}
          </div>
        )}
      </section>
    </div>
  );
}
