import { useQueries, useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';

import { UNAUTHORIZED_ERROR } from '../constants/custom';
import api from '../services/api';
import { CandidateAllResponse } from '../services/api/APIS/Events/types';

export const useCandidateAllAccess = (token: string, unitId: string) => {
  const { data: candidates, isLoading } = useCandidatesAll(token, unitId);
  const hasAccess = useMemo(() => {
    if (!candidates) return false;
    return candidates[0] !== UNAUTHORIZED_ERROR;
  }, [candidates, unitId]);

  return { hasAccess, isLoading };
};

export const useDecisionAllAccess = (token: string, unitId: string) => {
  const { data: decisions, isLoading } = useEventCongressDecisionAll(token, unitId);
  const hasAccess = useMemo(() => {
    if (!decisions) return false;
    return decisions[0] !== UNAUTHORIZED_ERROR;
  }, [decisions, unitId]);

  return { hasAccess, isLoading };
};

export const useCongressAll = (
  token: string,
  isFuture: string,
  isUnit: string,
  isChildDirect: string,
  isChildUnit: string,
  isParticipant: string,
  disabled = false,
) => {
  return useQuery(
    ['congress-list', [token, isFuture, isUnit, isChildDirect, isChildUnit, isParticipant]],
    () =>
      api.events.eventCongressAllGet(
        token,
        isFuture,
        isUnit,
        isChildDirect,
        isChildUnit,
        isParticipant,
      ),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useCongressDetail = (token: string, congressId: string) => {
  const { data: congress, isLoading: isDetailLoading } = useEventCongressDetail(token, congressId);
  const { hasAccess: hasCandidateAccess, isLoading: isCandidateLoading } = useCandidateAllAccess(
    token,
    congressId,
  );
  const { hasAccess: hasDecisionAccess, isLoading: isDecisionLoading } = useCandidateAllAccess(
    token,
    congressId,
  );

  const isLoading = isDetailLoading || isCandidateLoading || isDecisionLoading;

  const detail = {
    ...congress,
    hasCandidateAccess,
    hasDecisionAccess,
  };

  return { detail, isLoading };
};

export const useEventCongressDetail = (token: string, congressId: string, disabled = false) => {
  return useQuery(
    ['congress-detail', [token, congressId]],
    () => api.events.eventCongressDetailGet(token, congressId),
    {
      enabled: !!token && !!congressId && !disabled,
    },
  );
};

export const useCandidates = (token: string, congressId: string) => {
  const { data: candidates, isLoading } = useCandidatesAll(token, congressId);
  const photos = usePhotos(token, candidates || []);

  const list = candidates?.map((item: CandidateAllResponse) => {
    const photo = photos.map(item => item.data).find(logoItem => logoItem?.id === item.personId);
    return {
      ...item,
      photo: photo?.photoContent || '',
    };
  });

  return { list, isLoading };
};

export const useCandidatesAll = (token: string, congressId: string, disabled = false) => {
  return useQuery<any>(
    ['candidate-list', [token, congressId]],
    () => api.events.candidateAllGet(token, congressId),
    {
      enabled: !!token && !!congressId && !disabled,
    },
  );
};

export const usePhotos = <T extends { personId: string }>(token: string, data: T[]) => {
  return useQueries({
    queries: (data || []).map((item: T) => ({
      queryKey: ['person-photos', item.personId],
      queryFn: () => api.organizationUnit.personPhotoGet(token, item.personId),
      enabled: !!token && !!item.personId && item.personId !== 'empty',
      staleTime: Infinity,
    })),
  });
};

export const useCandidate = (token: string, candidateId: string) => {
  const { data: contacts, isLoading: isContactsLoading } = useCandidateContactAll(
    token,
    candidateId,
  );
  const { data: detail, isLoading: isDetailLoading } = useCandidateDetail(token, candidateId);
  const { data: person, isLoading: isPersonLoading } = useCandidateDetailPerson(token, candidateId);
  const { data: seminaries, isLoading: isSeminariesLoading } = useCandidateEducationSeminaryAll(
    token,
    candidateId,
  );
  const { data: functions, isLoading: isFunctionsLoading } = useCandidateFunctionAll(
    token,
    candidateId,
  );
  const { data: qualifications, isLoading: isQualificationsLoading } = useCandidateQualificationAll(
    token,
    candidateId,
  );
  const { data: recommendations, isLoading: isRecommendationsLoading } =
    useCandidateRecommendationAll(token, candidateId);

  const candidate = {
    ...detail,
    person,
    contacts,
    seminaries,
    functions,
    qualifications,
    recommendations,
  };

  const isLoading =
    isContactsLoading ||
    isDetailLoading ||
    isPersonLoading ||
    isSeminariesLoading ||
    isFunctionsLoading ||
    isQualificationsLoading ||
    isRecommendationsLoading;

  return { candidate, isLoading };
};

export const useCandidateContactAll = (token: string, candidateId: string, disabled = false) => {
  return useQuery(
    ['candidate-contact-list', [token, candidateId]],
    () => api.events.candidateContactAllGet(token, candidateId),
    {
      enabled: !!token && !!candidateId && !disabled,
    },
  );
};

export const useCandidateDetail = (token: string, candidateId: string, disabled = false) => {
  return useQuery(
    ['candidate-detail', [token, candidateId]],
    () => api.events.candidateDetailGet(token, candidateId),
    {
      enabled: !!token && !!candidateId && !disabled,
    },
  );
};

export const useCandidateDetailPerson = (token: string, candidateId: string, disabled = false) => {
  return useQuery(
    ['candidate-detail-person', [token, candidateId]],
    () => api.events.candidateDetailPersonGet(token, candidateId),
    {
      enabled: !!token && !!candidateId && !disabled,
    },
  );
};

export const useCandidateEducationSeminaryAll = (
  token: string,
  candidateId: string,
  disabled = false,
) => {
  return useQuery(
    ['candidate-education-seminary-list', [token, candidateId]],
    () => api.events.candidateEducationSeminaryAllGet(token, candidateId),
    {
      enabled: !!token && !!candidateId && !disabled,
    },
  );
};

export const useCandidateFunctionAll = (token: string, candidateId: string, disabled = false) => {
  return useQuery(
    ['candidate-function-list', [token, candidateId]],
    () => api.events.candidateFunctionAllGet(token, candidateId),
    {
      enabled: !!token && !!candidateId && !disabled,
    },
  );
};

export const useCandidateQualificationAll = (
  token: string,
  candidateId: string,
  disabled = false,
) => {
  return useQuery(
    ['candidate-qualification-list', [token, candidateId]],
    () => api.events.candidateQualificationAllGet(token, candidateId),
    {
      enabled: !!token && !!candidateId && !disabled,
    },
  );
};

export const useCandidateRecommendationAll = (
  token: string,
  candidateId: string,
  disabled = false,
) => {
  return useQuery(
    ['candidate-recommendation-list', [token, candidateId]],
    () => api.events.candidateRecommendationAllGet(token, candidateId),
    {
      enabled: !!token && !!candidateId && !disabled,
    },
  );
};

export const useCongressVote = (token: string, congressId: string, disabled = false) => {
  const { data: maxes, isLoading: isMaxesLoading } = useEventCongressFunctionAllMax(
    token,
    congressId,
  );
  const { data: candidates, isLoading: isCandidatesLoading } = useCandidatesAll(token, congressId);

  const fncCandidates: { [val: string]: CandidateAllResponse[] } = candidates?.reduce(
    (acc: { [val: string]: CandidateAllResponse[] }, item: CandidateAllResponse) => {
      if (item.function in acc) {
        acc[item.function].push(item);
      } else {
        acc[item.function] = [item];
      }
      return acc;
    },
    {},
  );

  const isLoading = isMaxesLoading || isCandidatesLoading;

  return { maxes, fncCandidates, isLoading };
};

export const useEventCongressFunctionAllMax = (
  token: string,
  congressId: string,
  disabled = false,
) => {
  return useQuery(
    ['congress-function-max', [token, congressId]],
    () => api.events.eventCongressFunctionAllMaxGet(token, congressId),
    {
      enabled: !!token && !!congressId && !disabled,
    },
  );
};

export const useEventCongressDecisionAll = (
  token: string,
  congressId: string,
  disabled = false,
) => {
  return useQuery(
    ['congress-decision-list', [token, congressId]],
    () => api.events.eventCongressDecisionAllGet(token, congressId),
    {
      enabled: !!token && !!congressId && !disabled,
    },
  );
};
