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

import CardContainer from '@material-hu/components/design-system/CardContainer';
import Autocomplete from '@material-hu/components/design-system/Inputs/Autocomplete';
import { type AutocompleteOption } from '@material-hu/components/design-system/Inputs/Autocomplete/types';

import useGetPathCourses from 'src/pages/dashboard/Learning/Paths/hooks/useGetPathCourses';
import { type NewPathFormValues } from 'src/pages/dashboard/Learning/Paths/types';
import { getFormattedPathCourse } from 'src/pages/dashboard/Learning/Paths/utils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { MIN_COURSES_TO_CREATE_PATH } from '../../../constants';

const CoursesSearch = () => {
  const { t } = useLokaliseTranslation('learning');
  const [searchQuery, setSearchQuery] = useState('');
  const {
    control,
    setValue,
    clearErrors,
    formState: { errors },
  } = useFormContext<NewPathFormValues>();

  const { data, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } =
    useGetPathCourses(searchQuery);

  const selectedCourses = useWatch({
    control,
    name: 'content.courses',
  });

  const courses = useMemo(
    () => data?.pages.flatMap(page => page.data.items) || [],
    [data],
  );

  const formattedCourses = useMemo(() => {
    const newCourses: AutocompleteOption[] = [];

    const selectedIdsSet = new Set(
      selectedCourses.map(({ courseId }) => courseId),
    );

    for (const course of courses) {
      const isAlreadySelected = selectedIdsSet.has(course.id);

      if (!isAlreadySelected) {
        newCourses.push({ label: course.title, value: course.id });
      }
    }

    return newCourses;
  }, [courses, selectedCourses]);

  const handleOnChange = (item: AutocompleteOption | null) => {
    if (!item) return;

    const foundCourse = courses.find(course => course.id === item.value);
    if (!foundCourse) return;

    const formattedCourse = getFormattedPathCourse(foundCourse);
    const newSelectedCourses = [...selectedCourses, formattedCourse];

    if (newSelectedCourses.length >= MIN_COURSES_TO_CREATE_PATH) {
      clearErrors('content.courses');
    }

    setValue('content.courses', newSelectedCourses);
    setSearchQuery('');
  };

  const hasError = !!errors.content?.courses;
  const helperText = hasError
    ? t('path.courses.empty.input_label', { count: MIN_COURSES_TO_CREATE_PATH })
    : undefined;

  return (
    <CardContainer fullWidth>
      <Autocomplete
        label={t('path.courses.search')}
        placeholder={t('common.name')}
        value={null}
        isServerFiltered
        options={formattedCourses}
        loading={isLoading || isFetchingNextPage}
        onLoadMore={fetchNextPage}
        hasMoreOptions={hasNextPage}
        onInputChange={(_, value) => setSearchQuery(value)}
        onChange={handleOnChange}
        key={selectedCourses.length}
        hasError={hasError}
        helperText={helperText}
      />
    </CardContainer>
  );
};

export default CoursesSearch;
