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

import ArrowDropUpIcon from '@material-hu/icons/material/ArrowDropUp';
import Accordion from '@material-hu/mui/Accordion';
import AccordionDetails from '@material-hu/mui/AccordionDetails';
import AccordionSummary from '@material-hu/mui/AccordionSummary';
import Checkbox from '@material-hu/mui/Checkbox';
import FormControlLabel from '@material-hu/mui/FormControlLabel';
import FormLabel from '@material-hu/mui/FormLabel';
import Grid from '@material-hu/mui/Grid';
import Radio from '@material-hu/mui/Radio';
import RadioGroup from '@material-hu/mui/RadioGroup';
import Typography from '@material-hu/mui/Typography';

import useSegmentationGroups from 'src/hooks/queryHooks/useSegmentationGroups';
import useGetAudience from 'src/pages/dashboard/Learning/Courses/hooks/useGetAudience';
import { type SegmentationType, type User } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';
import {
  formatFormSegmentation,
  isPublic,
  segmentationToIds,
  userSegmentationToUsers,
} from 'src/utils/segmentationUtils';

import CircularProgress from 'src/components/CircularProgress';
import {
  type GroupForSelection,
  type SegmentationForSelection,
} from 'src/components/FormInputs/FormSegmentation/types';
import {
  changeSegmentation,
  formatSegmentationForSelection,
} from 'src/components/FormInputs/FormSegmentation/utils';
import UsersAutocomplete from 'src/components/UsersAutocomplete';

export type CertificateSegmentationValue = {
  userSegmentation: User[];
  groupSegmentation: number[];
} | null;

type CertificateSegmentation = {
  name: string;
  courseId: number;
};

const CertificateSegmentation = ({
  name,
  courseId,
}: CertificateSegmentation) => {
  const { t } = useLokaliseTranslation('backoffice_only');
  const { control, watch, setValue } = useFormContext();

  const { data: audience, isLoading: audienceLoading } =
    useGetAudience(courseId);

  const courseIsPublic = isPublic({
    segmentation: audience?.segmentation,
    userSegmentation: audience?.userSegmentation,
  });

  const allowedItemIds: number[] | undefined = courseIsPublic
    ? undefined
    : segmentationToIds(audience?.segmentation ?? []);

  const allowedUsers = courseIsPublic
    ? undefined
    : userSegmentationToUsers(audience?.userSegmentation ?? []);

  const segmentDefaultValue: CertificateSegmentationValue = courseIsPublic
    ? { userSegmentation: [], groupSegmentation: [] }
    : (formatFormSegmentation(audience!) ?? {
        userSegmentation: [],
        groupSegmentation: [],
      });

  if (audienceLoading) {
    return <CircularProgress centered />;
  }

  return (
    <Controller
      name={name}
      control={control}
      render={({ field: { onChange, value } }) => {
        const isSegmented = !!value;

        return (
          <Grid container>
            <Grid
              item
              xs={12}
              sx={{ mb: 1 }}
            >
              <RadioGroup
                row
                value={isSegmented}
              >
                <FormControlLabel
                  control={<Radio sx={{ ml: 1 }} />}
                  label={t('backoffice_only:form_segmentation.all_users')}
                  value={false}
                  onChange={() => onChange(null)}
                />
                <FormControlLabel
                  control={<Radio sx={{ ml: 1 }} />}
                  label={t('backoffice_only:form_segmentation.segment')}
                  value
                  onChange={() =>
                    onChange(
                      segmentDefaultValue ?? {
                        userSegmentation: [],
                        groupSegmentation: [],
                      },
                    )
                  }
                />
              </RadioGroup>
            </Grid>
            {isSegmented && (
              <>
                {allowedUsers === undefined ? (
                  <>
                    <Grid
                      item
                      xs={12}
                      sm={3}
                    >
                      <FormLabel>
                        {t(
                          'backoffice_only:form_segmentation.segmentation_by_users',
                        )}
                      </FormLabel>
                    </Grid>
                    <Grid
                      item
                      xs={12}
                      sm={9}
                    >
                      <UsersAutocomplete
                        name={`${name}.userSegmentation`}
                        textFieldProps={{
                          placeholder: t(
                            'backoffice_only:form_segmentation.search_users',
                          ),
                        }}
                        autocompleteProps={{ multiple: true }}
                        defaultSearchOptions={{
                          enableEmptyQuery: true,
                          defaultLimit: 5,
                        }}
                      />
                    </Grid>
                  </>
                ) : (
                  allowedUsers.length > 0 && (
                    <>
                      <Grid
                        item
                        xs={12}
                        sm={3}
                        sx={{ mt: 1 }}
                      >
                        <FormLabel>
                          {t(
                            'backoffice_only:form_segmentation.segmentation_by_users',
                          )}
                        </FormLabel>
                      </Grid>
                      <Grid
                        item
                        xs={12}
                        sm={9}
                        sx={{ mt: 1 }}
                      >
                        <UsersAccordion
                          name={name}
                          allowedUsers={allowedUsers}
                          watch={watch}
                          setValue={setValue}
                        />
                      </Grid>
                    </>
                  )
                )}
                <Grid
                  item
                  xs={12}
                  sm={3}
                  sx={{ mt: 1 }}
                >
                  <FormLabel>
                    {t(
                      'backoffice_only:form_segmentation.segmentation_by_groups',
                    )}
                  </FormLabel>
                </Grid>
                <Grid
                  item
                  xs={12}
                  sm={9}
                  sx={{ mt: 1 }}
                >
                  <FilteredSegmentationItems
                    selectedItems={value?.groupSegmentation ?? []}
                    allowedItemIds={allowedItemIds}
                    onChange={itemId => {
                      const currentValue = watch(name);
                      const next = currentValue?.groupSegmentation ?? [];
                      const updated = next.includes(itemId)
                        ? next.filter((id: number) => id !== itemId)
                        : [...next, itemId];
                      onChange({ ...currentValue, groupSegmentation: updated });
                    }}
                  />
                </Grid>
              </>
            )}
          </Grid>
        );
      }}
    />
  );
};

type UsersAccordionProps = {
  name: string;
  allowedUsers: ReturnType<typeof userSegmentationToUsers>;
  watch: ReturnType<typeof useFormContext>['watch'];
  setValue: ReturnType<typeof useFormContext>['setValue'];
};

const UsersAccordion = ({
  name,
  allowedUsers,
  watch,
  setValue,
}: UsersAccordionProps) => {
  const { t } = useLokaliseTranslation('general');
  const currentUsers: User[] = watch(`${name}.userSegmentation`) ?? [];
  const checkedCount = allowedUsers.filter(u =>
    currentUsers.some(cu => (cu?.id ?? cu) === u.id),
  ).length;

  return (
    <Accordion
      defaultExpanded
      square
      disableGutters
      slotProps={{ transition: { unmountOnExit: true } }}
    >
      <AccordionSummary
        expandIcon={<ArrowDropUpIcon />}
        sx={{
          backgroundColor: '#DFEDFF',
          '& .MuiAccordionSummary-content': { alignItems: 'center' },
        }}
      >
        <Typography
          variant="subtitle1"
          fontWeight="fontWeightSemiBold"
        >
          {t('general:users')}
        </Typography>
        <Typography
          variant="subtitle2"
          sx={{ ml: 2 }}
        >
          ({checkedCount}/{allowedUsers.length})
        </Typography>
      </AccordionSummary>
      <AccordionDetails>
        <Grid container>
          {allowedUsers.map(user => {
            const isChecked = currentUsers.some(
              cu => (cu?.id ?? cu) === user.id,
            );
            return (
              <Grid
                item
                xs={12}
                sm={6}
                key={user.id}
              >
                <FormControlLabel
                  control={
                    <Checkbox
                      checked={isChecked}
                      onChange={() => {
                        const next = isChecked
                          ? currentUsers.filter(
                              cu => (cu?.id ?? cu) !== user.id,
                            )
                          : [...currentUsers, user];
                        setValue(`${name}.userSegmentation` as any, next);
                      }}
                    />
                  }
                  label={`${user.firstName} ${user.lastName}`}
                />
              </Grid>
            );
          })}
        </Grid>
      </AccordionDetails>
    </Accordion>
  );
};

type FilteredSegmentationItemsProps = {
  selectedItems: number[];
  allowedItemIds?: number[];
  onChange: (itemId: number) => void;
};

const FilteredSegmentationItems = ({
  selectedItems,
  allowedItemIds,
  onChange,
}: FilteredSegmentationItemsProps) => {
  const [segmentation, setSegmentation] = useState<SegmentationForSelection>(
    [],
  );

  const segmentationQuery = useSegmentationGroups({
    onSuccess: (data: GroupForSelection[]) => {
      const filtered = allowedItemIds?.length
        ? data
            .map(group => ({
              ...group,
              items: group.items?.filter(item =>
                allowedItemIds.includes(item.id),
              ),
            }))
            .filter(group => group.items?.length)
        : data;
      setSegmentation(
        formatSegmentationForSelection(
          filtered as unknown as SegmentationType[],
          selectedItems,
        ),
      );
    },
  });

  useEffect(() => {
    if (segmentation.length) {
      setSegmentation(
        formatSegmentationForSelection(
          segmentation.map(g => ({
            ...g,
            items: g.items,
          })) as unknown as SegmentationType[],
          selectedItems,
        ),
      );
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedItems]);

  if (segmentationQuery.isLoading) {
    return <CircularProgress centered />;
  }

  return (
    <>
      {segmentation.map((group, groupIndex) => (
        <Accordion
          defaultExpanded={groupIndex === 0}
          square
          disableGutters
          key={group.id}
          slotProps={{ transition: { unmountOnExit: true } }}
        >
          <AccordionSummary
            expandIcon={<ArrowDropUpIcon />}
            sx={{
              backgroundColor: '#DFEDFF',
              '& .MuiAccordionSummary-content': { alignItems: 'center' },
            }}
          >
            <Typography
              variant="subtitle1"
              fontWeight="fontWeightSemiBold"
            >
              {group.name}
            </Typography>
            <Typography
              variant="subtitle2"
              sx={{ ml: 2 }}
            >
              ({group.checkedCount}/{group.count})
            </Typography>
          </AccordionSummary>
          <AccordionDetails>
            <Grid container>
              {group.items.map((item, itemIndex) => (
                <Grid
                  item
                  xs={12}
                  sm={6}
                  key={item.id}
                >
                  <FormControlLabel
                    control={
                      <Checkbox
                        checked={item.checked}
                        onChange={() => {
                          setSegmentation(prev =>
                            changeSegmentation(
                              prev,
                              groupIndex,
                              itemIndex,
                              !item.checked,
                            ),
                          );
                          onChange(item.id);
                        }}
                      />
                    }
                    label={item.name}
                  />
                </Grid>
              ))}
            </Grid>
          </AccordionDetails>
        </Accordion>
      ))}
    </>
  );
};

export default CertificateSegmentation;
