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

import {
  EMAIL_CONTACT_TYPE,
  MOBILE_CONTACT_TYPE,
  PHONE_CONTACT_TYPE,
  UNAUTHORIZED_ERROR,
} from '../constants/custom';
import { getDateAsString } from '../helpers/stringHelpers';
import api from '../services/api';
import { PersonDetailResponse } from '../services/api/APIS/OrganizationUnit/types';

export const usePerson = (token: string, personId: string, isFromCatalog: boolean) => {
  const { data: details, isLoading: isDetailLoading } = usePersonDetail(token, personId);
  const { data: contacts, isLoading: isContactsLoading } = usePersonContactAll(token, personId);
  const { data: photo, isLoading: isPhotoLoading } = usePersonPhoto(token, personId);

  const { data: detailsOther, isLoading: isDetailOtherLoading } = usePersonOtherDetail(
    token,
    personId,
    !isFromCatalog,
  );
  const { data: personFunction, isLoading: isFunctionLoading } = useFunctionAll(
    token,
    personId,
    !isFromCatalog || details?.displayFunction,
  );
  const { data: qualification, isLoading: isQualificationLoading } = useQualificationAll(
    token,
    personId,
    isFromCatalog || details?.displayQualification,
  );
  const { data: offer, isLoading: isOfferLoading } = useOfferAll(
    token,
    personId,
    !isFromCatalog || details?.displayOffer,
  );
  const { data: membership, isLoading: isMembershipLoading } = useMembershipAllPerson(
    token,
    personId,
    !isFromCatalog || details?.displayMembership,
  );

  const birthday = new Date(details?.birthday ?? 0);
  const phone = contacts?.find(
    item => item.contactTypeId === PHONE_CONTACT_TYPE || item.contactTypeId === MOBILE_CONTACT_TYPE,
  );
  const email = contacts?.find(item => item.contactTypeId === EMAIL_CONTACT_TYPE);

  const formattedDetail: PersonDetailResponse = details;

  const person = {
    ...formattedDetail,
    ...detailsOther,
    birthday: getDateAsString(birthday),
    ...photo,
    contacts: contacts?.filter(
      item =>
        ![EMAIL_CONTACT_TYPE, PHONE_CONTACT_TYPE, MOBILE_CONTACT_TYPE].includes(item.contactTypeId),
    ),
    phone,
    email,
    function: personFunction,
    qualification,
    offer,
    membership,
  };

  const isLoading =
    isDetailLoading ||
    isContactsLoading ||
    isPhotoLoading ||
    (!isFromCatalog && isDetailOtherLoading) ||
    ((isFromCatalog || details?.displayQualification) && isQualificationLoading) ||
    ((!isFromCatalog || details?.displayFunction) && isFunctionLoading) ||
    ((!isFromCatalog || details?.displayOffer) && isOfferLoading) ||
    ((!isFromCatalog || details?.displayMembership) && isMembershipLoading);

  return { person, isLoading };
};

export const usePersonDetail = (token: string, personId: string) => {
  return useQuery(
    ['person-detail', [token, personId]],
    () => api.organizationUnit.personDetailGet(token, personId),
    {
      enabled: !!token && !!personId,
    },
  );
};

export const usePersonContactAll = (token: string, personId: string) => {
  return useQuery(
    ['person-contact-all', [token, personId]],
    () => api.organizationUnit.personContactAllGet(token, personId),
    {
      enabled: !!token && !!personId,
    },
  );
};

export const usePersonOtherDetail = (token: string, personId: string, permission = true) => {
  return useQuery(
    ['person-detail-other', [token, personId]],
    () => api.organizationUnit.personOtherDetailGet(token, personId),
    {
      enabled: !!token && !!personId && permission,
    },
  );
};

export const useFunctionAll = (token: string, personId: string, permission = true) => {
  return useQuery(
    ['function-person-all', [token, personId]],
    () => api.organizationUnit.functionPersonAllGet(token, personId),
    {
      enabled: !!token && !!personId && permission,
    },
  );
};

export const useQualificationAll = (token: string, personId: string, permission = true) => {
  return useQuery(
    ['qualification-all', [token, personId]],
    () => api.organizationUnit.qualificationAllGet(token, personId),
    {
      enabled: !!token && !!personId && permission,
    },
  );
};

export const useOfferAll = (token: string, personId: string, permission = true) => {
  return useQuery(
    ['offer-all', [token, personId]],
    () => api.organizationUnit.offerAllGet(token, personId),
    {
      enabled: !!token && !!personId && permission,
    },
  );
};

export const useMembershipAllPerson = (token: string, personId: string, permission = true) => {
  return useQuery(
    ['membership-all-person', [token, personId]],
    () => api.organizationUnit.membershipAllGet(token, personId),
    {
      enabled: !!token && !!personId && permission,
    },
  );
};

export const usePersonPhoto = (token: string, personId: string) => {
  return useQuery(
    ['person-photo', token, personId],
    () => api.organizationUnit.personPhotoGet(token, personId),
    {
      enabled: !!token && !!personId,
    },
  );
};

export const useHasPersonAccess = <T extends { personId: string }>(token: string, data: T[]) => {
  return useQueries({
    queries: (data || []).map(item => ({
      queryKey: ['person-access', item.personId, token],
      queryFn: () =>
        api.organizationUnit.personDetailGet(token, item.personId).then(res => {
          return {
            id: item.personId,
            hasAccess: res !== UNAUTHORIZED_ERROR,
          };
        }),
      enabled: !!token && !!item.personId,
      staleTime: Infinity,
    })),
  });
};
