import { graphql, useLazyLoadQuery, usePaginationFragment } from "react-relay";
import { useParams } from "react-router-dom";
import { useEffect, useMemo, useRef } from "react";
import type { ProfileQuery as ProfileQueryType } from "./__generated__/ProfileQuery.graphql";
import type { Profile_plays$key } from "./__generated__/Profile_plays.graphql";
import TrackItem from "./TrackItem";
import ProfileLayout from "./ProfileLayout";

export default function Profile() {
  const { handle } = useParams<{ handle: string }>();

  const queryVariables = useMemo(() => {
    return {
      where: { actorHandle: { eq: handle } },
    };
  }, [handle]);

  const queryData = useLazyLoadQuery<ProfileQueryType>(
    graphql`
      query ProfileQuery($where: FmTealAlphaFeedPlayWhereInput!) {
        ...Profile_plays @arguments(where: $where)
      }
    `,
    queryVariables,
  );

  const { data, loadNext, hasNext, isLoadingNext } = usePaginationFragment<
    ProfileQueryType,
    Profile_plays$key
  >(
    graphql`
      fragment Profile_plays on Query
      @refetchable(queryName: "ProfilePaginationQuery")
      @argumentDefinitions(
        cursor: { type: "String" }
        count: { type: "Int", defaultValue: 20 }
        where: { type: "FmTealAlphaFeedPlayWhereInput!" }
      ) {
        fmTealAlphaFeedPlays(
          first: $count
          after: $cursor
          sortBy: [{ field: playedTime, direction: desc }]
          where: $where
        )
          @connection(
            key: "Profile_fmTealAlphaFeedPlays"
            filters: ["where", "sortBy"]
          ) {
          totalCount
          edges {
            node {
              ...TrackItem_play
            }
          }
        }
      }
    `,
    queryData,
  );

  const loadMoreRef = useRef<HTMLDivElement>(null);

  const plays = useMemo(
    () =>
      data?.fmTealAlphaFeedPlays?.edges?.map((edge) => edge.node).filter((n) =>
        n != null
      ) || [],
    [data?.fmTealAlphaFeedPlays?.edges],
  );

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [handle]);

  useEffect(() => {
    if (!loadMoreRef.current || !hasNext) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && hasNext && !isLoadingNext) {
          loadNext(20);
        }
      },
      { threshold: 0.1 },
    );

    observer.observe(loadMoreRef.current);

    return () => observer.disconnect();
  }, [hasNext, isLoadingNext, loadNext]);

  return (
    //@ts-expect-error: idk
    <ProfileLayout handle={handle!}>
      <div className="mb-8">
        <p className="text-xs text-zinc-500 uppercase tracking-wider">
          {(data?.fmTealAlphaFeedPlays?.totalCount ?? 0).toLocaleString()}{" "}
          scrobbles
        </p>
      </div>

      <div className="space-y-1">
        {plays && plays.length > 0
          ? (
            plays.map((play, index) => <TrackItem key={index} play={play} />)
          )
          : (
            <p className="text-zinc-600 text-center py-8 text-xs uppercase tracking-wider">
              No tracks found for this user
            </p>
          )}
      </div>

      {hasNext && (
        <div ref={loadMoreRef} className="py-12 text-center">
          {isLoadingNext
            ? (
              <p className="text-xs text-zinc-600 uppercase tracking-wider">
                Loading...
              </p>
            )
            : (
              <p className="text-xs text-zinc-700 uppercase tracking-wider">
                ·
              </p>
            )}
        </div>
      )}
    </ProfileLayout>
  );
}
