import { useEffect, useMemo, useRef, useState } from 'react';
import { useFormContext } from 'react-hook-form';

import Audience from '@material-hu/components/composed-components/audience/Audience';
import {
  type AudienceFormValues,
  type CriteriaEntry,
  CriteriaType,
  type IndividualCriteriaEntry,
} from '@material-hu/components/composed-components/audience/Audience/types';
import AudienceSkeleton from '@material-hu/components/composed-components/audience/AudienceSkeleton';

import { librariesKeys } from 'src/pages/dashboard/HuLibraries/queries';
import { type Article } from 'src/pages/dashboard/HuLibraries/types';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { infiniteQueryDataParser } from 'src/utils/pagination';

import useAudienceFormCount from 'src/components/Audience/hooks/useAudienceFormCount';
import useGetAudienceItems from 'src/components/Audience/hooks/useGetAudienceItems';
import useGetAudienceUsers from 'src/components/Audience/hooks/useGetAudienceUsers';
import useIndividualDrawerCount from 'src/components/Audience/hooks/useIndividualDrawerCount';
import useIndividualDrawerService from 'src/components/Audience/hooks/useIndividualDrawerService';
import useSegmentationDrawerCount from 'src/components/Audience/hooks/useSegmentationDrawerCount';
import useSegmentationDrawerService from 'src/components/Audience/hooks/useSegmentationDrawerService';
import useSegmentationFieldItems from 'src/components/Audience/hooks/useSegmentationFieldItems';
import useSegmentationValueItems from 'src/components/Audience/hooks/useSegmentationValueItems';
import useSelectedUsers from 'src/components/Audience/hooks/useSelectedUsers';
import { audienceQueryToCriterias } from 'src/components/Audience/utils/audienceQueryToCriterias';
import { criteriasToSegmentationExpression } from 'src/components/Audience/utils/criteriasToSegmentationExpression';
import {
  getIndividualDescription,
  getSegmentationDescription,
} from 'src/components/Audience/utils/descriptions';
import { getCollaboratorsService } from 'src/components/Audience/utils/getCollaboratorsService';

type ArticleAudienceProps = {
  article: Article;
};

const ArticleAudience = ({ article }: ArticleAudienceProps) => {
  const { t } = useLokaliseTranslation('libraries');

  const {
    valueItems,
    itemToGroupMap,
    isLoading: itemsLoading,
  } = useGetAudienceItems();

  const defaultCriterias = useMemo(
    () =>
      audienceQueryToCriterias(
        article.audiencesQuery,
        itemToGroupMap,
        valueItems,
      ),
    [article.audiencesQuery, itemToGroupMap, valueItems],
  );

  const form = useFormContext<AudienceFormValues>();
  const { reset } = form;

  const hasResetRef = useRef(false);

  const [ready, setReady] = useState(false);

  useEffect(() => {
    if (!itemsLoading && !hasResetRef.current) {
      reset({ criterias: defaultCriterias });
      hasResetRef.current = true;
      setReady(true);
    }
  }, [itemsLoading, defaultCriterias, reset]);

  const criterias = form.watch('criterias') ?? [];

  const expression = useMemo(
    () => criteriasToSegmentationExpression(criterias),
    [criterias],
  );

  const collaboratorsService = useMemo(
    () => getCollaboratorsService(expression),
    [expression],
  );

  const segmentationCollaboratorsReach = useMemo(
    () => ({
      queryKey: librariesKeys.audience.collaborators.segmentation().join(', '),
      useCount: useSegmentationDrawerCount,
      useService: useSegmentationDrawerService,
    }),
    [],
  );

  const individualCollaboratorsReach = useMemo(
    () => ({
      queryKey: librariesKeys.audience.collaborators.individual().join(', '),
      useCount: useIndividualDrawerCount,
      useService: useIndividualDrawerService,
    }),
    [],
  );

  const selectedUserIds = useMemo(() => {
    let ids: number[] = [];
    criterias.forEach((criteria: CriteriaEntry) => {
      if (criteria.type === CriteriaType.INDIVIDUAL) {
        ids = [...ids, ...[...criteria.userIds].map(Number)];
      }
    });
    return ids;
  }, [criterias]);

  const userNamesMap = useSelectedUsers(selectedUserIds);

  const handleGetIndividualDescription = (entry: IndividualCriteriaEntry) =>
    getIndividualDescription(entry, userNamesMap);

  if (!ready) return <AudienceSkeleton />;

  return (
    <Audience
      title={t('article.audience.title')}
      description={t('article.audience.description')}
      showAllSelectedAlert={!article.parentId}
      segmentationDrawerProps={{
        collaboratorsReach: segmentationCollaboratorsReach,
        inputProps: {
          dynamicItems: {
            useFieldItems: useSegmentationFieldItems,
            useValueItems: useSegmentationValueItems,
          },
        },
      }}
      individualDrawerProps={{
        inputProps: {
          useUsersQuery: useGetAudienceUsers,
          usersQueryDataParser: infiniteQueryDataParser,
        },
        collaboratorsReach: individualCollaboratorsReach,
      }}
      selectedCollaboratorsDrawerProps={{
        service: collaboratorsService,
        queryKey: librariesKeys.audience.selectedCollaborators().join(', '),
      }}
      getSegmentationDescription={getSegmentationDescription}
      getIndividualDescription={handleGetIndividualDescription}
      useCount={useAudienceFormCount}
    />
  );
};

export default ArticleAudience;
