import { useQuery } from '@tanstack/react-query';
import { uniq } from 'lodash-es';
import { useEffect, useState } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import useClip from '@/hooks/useClip';

import { fetchAllEdits } from '../fetchers/fetchEdits';
import { Edit } from '../types';

export default function useEditAncestryQuery(clipId: string) {
  const { clips, session } = useStores();
  const { clip } = useClip(clipId);
  const [enabled, setEnabled] = useState(clip?.status === 'complete');
  const queryResult = useQuery({
    enabled: clip?.status === 'complete',
    staleTime: 0,
    queryKey: ['parentEdits', clipId],
    queryFn: async () => {
      if (clip?.status !== 'complete') {
        return {
          parentEdits: [],
          childEdits: [],
        };
      }
      const response = await fetchAllEdits(clips.apiClient, clipId);

      const ownedChildren = response.child_clips.filter(
        (c) => c.clip.user_id === session.user?.id
      );

      const directDescendants = ownedChildren.filter(({ parent_ids }) =>
        parent_ids.includes(clipId)
      );

      const fullSongDescendants = directDescendants.filter(({ relationship }) =>
        ['CI', 'CON', 'CR', 'FA', 'SP'].includes(relationship)
      );

      const editDescendants = directDescendants.filter(({ relationship }) =>
        ['EX', 'INF', 'INT', 'OU'].includes(relationship)
      );

      const childEdits: Edit[] = editDescendants.map(({ clip }, index) => {
        const clipId = clip.id;
        const fullSong = fullSongDescendants.find(({ parent_ids }) =>
          parent_ids.includes(clipId)
        );
        return {
          index,
          clipId,
          clip,
          songId: fullSong?.clip.id || null,
        };
      });

      const directParents = uniq(
        ownedChildren
          .filter(({ clip }) => clip.id === clipId)
          .map(({ parent_ids }) => parent_ids)
          .flat()
      )
        .map(
          (parentId) => ownedChildren.find(({ clip }) => clip.id === parentId)!
        )
        .filter(Boolean);

      // feels like we probably do actually need this
      // const fullSongParents = directParents.filter(({ relationship }) =>
      //   ['CI', 'CON', 'CR', 'FA', 'SP'].includes(relationship)
      // );
      const editParents = directParents.filter(({ relationship }) =>
        ['EX', 'INF', 'INT', 'OU'].includes(relationship)
      );
      const parentEdits: Edit[] = editParents.map(
        ({ clip, parent_ids }, index) => {
          const clipId = clip.id;
          const fullSong = response.root_clips.find((clip) =>
            parent_ids.includes(clip.id)
          );
          return {
            clipId,
            clip,
            songId: fullSong?.id || null,
            index,
          };
        }
      );
      return {
        parentEdits,
        childEdits,
      };
    },
  });

  useEffect(() => {
    const shouldEnable = clip?.status === 'complete';
    if (shouldEnable !== enabled) {
      setEnabled(shouldEnable);
      if (shouldEnable) {
        queryResult.refetch();
      }
    }
  }, [enabled, clip?.status]);

  return queryResult;
}
