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

import { UNAUTHORIZED_ERROR } from '../constants/custom';
import api from '../services/api';
import {
  EventEducationAllResponse,
  EventEducationCourseTermAllResponse,
  EventEducationOtherIllustrativePhotoAllResponse,
} from '../services/api/APIS/Events/types';
import { showFeedback } from '../services/feedback/showFeedback';
import { useUserInfo } from './useStorage';

export const useEducation = (
  token: string,
  educationType: string,
  isFuture: string,
  year: string,
  relationType: string,
) => {
  const {
    data: educationList,
    refetch: refetchList,
    isFetching: isEducationListLoading,
  } = useEducationList(token, educationType, isFuture, year, relationType);

  const logos = useLogos(token, educationList || []);
  const applicationAccesses = useEducationApplicationAccess(token, educationList || []);

  const list = educationList?.map(item => {
    const logo = logos.map(item => item.data).find(logoItem => logoItem?.id === item.logoId);
    const hasApplicationAccess = applicationAccesses
      .map(item => item.data)
      .find(applicationAccessItem => applicationAccessItem?.id === item.id)?.hasApplicationAccess;
    return {
      ...item,
      logo: logo?.documentContent || '',
      hasApplicationAccess,
    };
  });

  const isLoading = isEducationListLoading || applicationAccesses.some(item => item.isLoading);

  return { list, refetchList, isLoading };
};

export const useEducationList = (
  token: string,
  educationType: string,
  isFuture: string,
  year: string,
  relationType: string,
  disabled = false,
) => {
  return useQuery(
    ['education-list', [token, educationType, isFuture, year, relationType]],
    () =>
      api.events.eventEducationAllMyActionsGet(token, educationType, isFuture, year, relationType),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEducationListSearch = (
  token: string,
  name: string,
  year: string,
  groupId: string,
  typeId: string,
  disabled = false,
) => {
  return useQuery(
    ['education-list', [token, name, year, groupId, typeId]],
    () => api.events.eventEducationAllGet(token, name, year, groupId, typeId),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useLogos = (token: string, data: EventEducationAllResponse[]) => {
  return useQueries({
    queries: (data || []).map(item => ({
      queryKey: ['logos', item.logoId],
      queryFn: () => api.documentStorage.documentDetailDataGet(token, item.logoId),
      enabled: !!token && !!item.logoId && item.logoId !== 'empty',
      staleTime: Infinity,
    })),
  });
};

export const useEducationApplicationAccess = (token: string, data: EventEducationAllResponse[]) => {
  const [userInfo] = useUserInfo();
  return useQueries({
    queries: (data || []).map(item => ({
      queryKey: ['has-access-application', item.id, userInfo.personId],
      queryFn: () =>
        api.events
          .eventEducationCourseDetailEnrollGet(token, userInfo.personId, item.id)
          .then(res => {
            return {
              id: item.id,
              hasApplicationAccess: res !== UNAUTHORIZED_ERROR,
            };
          }),
      enabled: !!token && !!item.id,
      staleTime: Infinity,
    })),
  });
};

export const useEducationTypes = (token: string, disabled = false) => {
  return useQuery(['education-types', [token]], () => api.events.eventEducationTypeAllGet(token), {
    enabled: !!token && !disabled,
  });
};

export const useEducationGroups = (token: string, disabled = false) => {
  return useQuery(
    ['education-groups', [token]],
    () => api.events.eventEducationGroupAllGet(token),
    {
      enabled: !!token && !disabled,
    },
  );
};

export const useEducationApplication = (
  token: string,
  personId: string,
  educationId: string,
  disabled = false,
) => {
  return useQuery(
    ['education-application', [token, personId, educationId]],
    () => api.events.eventEducationCourseDetailEnrollGet(token, personId, educationId),
    {
      enabled: !!token && !!personId && !!educationId && !disabled,
    },
  );
};

export const useEducationDetail = (token: string, educationId: string) => {
  const { data: detail, isLoading: isDetailLoading } = useEventEducationDetail(token, educationId);
  const { data: courses, isLoading: isCoursesLoading } = useEventEducationCourseAll(
    token,
    educationId,
  );
  const { data: terms, isLoading: isTermsLoading } = useEventEducationCourseTermAllGet(
    token,
    educationId,
  );

  const year = new Date(detail?.startDate || new Date()).getFullYear().toString();
  const { data: fullList, refetch } = useEducationListSearch(
    token,
    '',
    year,
    '',
    '',
    !detail?.startDate.length,
  );
  if (token.length && detail && detail?.startDate.length) {
    refetch();
  }
  const enrollId = fullList?.find(item => item.id === educationId)?.enrollId;
  const locations = useTermsLocations(token, terms || []);

  const termWithLocations = terms?.map(term => {
    const location = locations.find(item => item.data?.id === term.locationId);
    return {
      ...term,
      locationInfo: location?.data,
    };
  });

  const isLoading =
    isDetailLoading || isCoursesLoading || isTermsLoading || locations.some(item => item.isLoading);

  return { detail, enrollId, courses, termWithLocations, isLoading };
};

export const useEventEducationCourseAll = (
  token: string,
  educationId: string,
  disabled = false,
) => {
  return useQuery(
    ['education-courses-all', [token, educationId]],
    () => api.events.eventEducationCourseAllGet(token, educationId),
    {
      enabled: !!token && !!educationId && !disabled,
    },
  );
};

export const useEventEducationDetail = (token: string, educationId: string, disabled = false) => {
  return useQuery(
    ['education-detail', [token, educationId]],
    () => api.events.eventEducationDetailGet(token, educationId),
    {
      enabled: !!token && !!educationId && !disabled,
    },
  );
};

export const useEventEducationCourseTermAllGet = (
  token: string,
  educationId: string,
  disabled = false,
) => {
  return useQuery(
    ['education-terms-all', [token, educationId]],
    () => api.events.eventEducationCourseTermAllGet(token, educationId),
    {
      enabled: !!token && !!educationId && !disabled,
    },
  );
};

export const useTermsLocations = (token: string, data: EventEducationCourseTermAllResponse[]) => {
  return useQueries({
    queries: (data || []).map(item => ({
      queryKey: ['termLocation', item.locationId],
      queryFn: () => api.events.eventEducationLocationDetailGet(token, item.locationId),
      enabled: !!token && !!item.locationId,
      staleTime: Infinity,
    })),
  });
};

export const useEnrollReminderDetail = (token: string, reminderId: string, disabled = false) => {
  return useQuery(
    ['enroll-reminder-detail', [token, reminderId]],
    () => api.events.eventEducationCourseEnrollReminderDetailGet(token, reminderId),
    {
      enabled: !!token && !!reminderId && !disabled,
    },
  );
};

export const useEnrollReminderAdd = (
  token: string,
  personId: string,
  id: string,
  educationId: string,
  setReminderId: (value: string) => void,
) => {
  return useMutation(
    ['enroll-reminder-add', [token, personId, id, educationId]],
    (hours: string) =>
      api.events.eventEducationCourseEnrollReminderAdd(token, personId, id, educationId, hours),
    {
      onSuccess: newId => {
        setReminderId(newId || '');
        showFeedback({
          title: 'Upozornění úspěšně nastaveno.',
          type: 'success',
        });
      },
      onError: () => {
        showFeedback({
          title: `Při nastavování upozornění došlo k chybě. Zkontrolujte prosím vaše internetové připojení.`,
          type: 'danger',
        });
      },
    },
  );
};

export const useEnrollReminderDelete = (token: string, setReminderId: (value: string) => void) => {
  return useMutation(
    ['enroll-reminder-delete', [token]],
    (reminderId: string) => api.events.eventEducationCourseEnrollReminderDelete(token, reminderId),
    {
      onSuccess: () => {
        setReminderId('');
        showFeedback({
          title: 'Upozornění úspěšně zrušeno.',
          type: 'success',
        });
      },
      onError: err => {
        showFeedback({
          title: `Při rušení upozornění došlo k chybě. Zkontrolujte prosím vaše internetové připojení.`,
          type: 'danger',
          err,
        });
      },
    },
  );
};

export const useEventEducationOtherDetailGet = (
  token: string,
  educationId: string,
  courseId?: string,
  disabled = false,
) => {
  return useQuery(
    ['education-other-detail', [token, educationId, courseId]],
    () => api.events.eventEducationOtherDetailGet(token, educationId, courseId || ''),
    {
      enabled: !!token && !!educationId && !disabled,
    },
  );
};

export const useEventEducationPhotos = (
  token: string,
  educationId: string,
  courseId?: string,
  disabled = false,
) => {
  const { data: photosList, isLoading: isPhotosLoading } =
    useEventEducationOtherIllustrativePhotoAllGet(token, educationId, courseId, disabled);

  const documentsSmall = useDocumentsSmall(token, photosList || []);
  const documents = useDocuments(token, photosList || []);

  const images = photosList?.map(item => {
    const documentSmall = documentsSmall
      .map(item => item.data)
      .find(document => document?.id === item.documentIdSmall);
    const document = documents
      .map(item => item.data)
      .find(document => document?.id === item.documentId);

    return {
      ...item,
      documentSmall: documentSmall?.documentContent || '',
      document: document?.documentContent || '',
    };
  });

  const isLoading =
    isPhotosLoading ||
    documentsSmall.some(item => item.isLoading) ||
    documents.some(item => item.isLoading);
  return { images, isLoading };
};

export const useEventEducationOtherIllustrativePhotoAllGet = (
  token: string,
  educationId: string,
  courseId?: string,
  disabled = false,
) => {
  return useQuery(
    ['education-other-illustrative-photo-all', [token, educationId, courseId]],
    () => api.events.eventEducationOtherIllustrativePhotoAllGet(token, educationId, courseId || ''),
    {
      enabled: !!token && !!educationId && !disabled,
    },
  );
};

export const useDocumentsSmall = (
  token: string,
  data: EventEducationOtherIllustrativePhotoAllResponse[],
) => {
  return useQueries({
    queries: (data || []).map(item => ({
      queryKey: ['documents-small', item.documentIdSmall],
      queryFn: () => api.documentStorage.documentDetailDataGet(token, item.documentIdSmall),
      enabled: !!token && !!item.documentIdSmall,
      staleTime: Infinity,
    })),
  });
};

export const useDocuments = (
  token: string,
  data: EventEducationOtherIllustrativePhotoAllResponse[],
) => {
  return useQueries({
    queries: (data || []).map(item => ({
      queryKey: ['documents', item.documentId],
      queryFn: () => api.documentStorage.documentDetailDataGet(token, item.documentId),
      enabled: !!token && !!item.documentId,
      staleTime: Infinity,
    })),
  });
};
