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

import { useModal } from '@material-hu/hooks/useModal';
import { AccordionSummaryProps } from '@material-hu/mui/AccordionSummary';
import Alert from '@material-hu/mui/Alert';

import FormControlLabel from '@material-hu/mui/FormControlLabel';
import FormLabel from '@material-hu/mui/FormLabel';
import Grid from '@material-hu/mui/Grid';
import Radio, { RadioProps } from '@material-hu/mui/Radio';
import RadioGroup from '@material-hu/mui/RadioGroup';
import { SxProps } from '@material-hu/mui/styles';

import Button from '@material-hu/components/design-system/Buttons/Button';

import { DefaultEmptyAutoCompleteOptions } from 'src/types/form';
import { addOrRemove } from 'src/utils/arrayUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { validateSegmentationRule } from 'src/utils/validation';

import { Props as FormAutoCompleteProps } from 'src/components/FormInputs/FormAutocomplete';
import UsersAutocomplete from 'src/components/UsersAutocomplete';

import SegmentationItems from './SegmentationItems';
import SegmentationModal from './SegmentationModal';
import { useSimpleSegmentationPreview } from './utils';

export type FormSegmentationValue = {
  userSegmentation: any[];
  groupSegmentation: any[];
} | null;

export type FormSegmentationProps = {
  showLabel?: boolean;
  name: string;

  segmentationErrorMessage: string;
  accordionSummaryProps?: AccordionSummaryProps;
  radioProps?: RadioProps;
  onChange?: (newValue: FormSegmentationValue) => void;
  onChangeType?: (newValue: FormSegmentationValue) => void;
  autoCompleteDefaultSearchOptions?: DefaultEmptyAutoCompleteOptions;
  autocompleteProps?: FormAutoCompleteProps['autocompleteProps'];
  useAudienceApi?: boolean;
  labelSx?: SxProps;
  label?: string;
};

const FormSegmentation = ({
  showLabel = true,
  name,
  segmentationErrorMessage,
  accordionSummaryProps = {},
  radioProps = {},
  onChange: onChangeProp = () => null,
  onChangeType = () => null,
  autoCompleteDefaultSearchOptions = undefined,
  useAudienceApi = false,
  labelSx,
  autocompleteProps = {},
  label,
}: FormSegmentationProps) => {
  const { t } = useLokaliseTranslation('backoffice_only');
  const { control, watch } = useFormContext();
  // The value provided by the top Controller is not updated correctly by the nested Crontroller in UsersAutocomplete
  const userSegmentationValue = watch(`${name}.userSegmentation`);

  const { totalUsers, loading } = useSimpleSegmentationPreview(
    name,
    useAudienceApi,
  );

  const { modal, showModal } = useModal(
    SegmentationModal,
    { maxWidth: 'sm', fullWidth: true },
    { name, useAudienceApi: true },
  );

  const handleChange = (
    newValue: FormSegmentationValue,
    onChange: Function,
  ) => {
    onChange(newValue);
    onChangeProp(newValue);
  };

  const handleChangeType = (
    newValue: FormSegmentationValue,
    onChange: Function,
  ) => {
    handleChange(newValue, onChange);
    onChangeType(newValue);
  };

  return (
    <Controller
      name={name}
      control={control}
      rules={{ validate: validateSegmentationRule(segmentationErrorMessage) }}
      render={({ field: { onChange, value }, fieldState: { error } }) => {
        const isSegmented = !!value;
        const { groupSegmentation } = value || {};

        useEffect(() => {
          if (isSegmented) {
            handleChange(
              { ...value, userSegmentation: userSegmentationValue },
              onChange,
            ); // we need to call the onChange function to revalidate the field
          }
        }, [userSegmentationValue, isSegmented]);

        return (
          <Grid container>
            {modal}
            <Grid
              item
              xs={6}
              sx={{ mb: 1 }}
            >
              {showLabel && (
                <FormLabel sx={labelSx || {}}>
                  {label || t('backoffice_only:form_segmentation.audience')}
                </FormLabel>
              )}
              <RadioGroup
                row
                value={isSegmented}
              >
                <FormControlLabel
                  control={
                    <Radio
                      {...radioProps}
                      sx={{ ml: 1, ...radioProps?.sx }}
                    />
                  }
                  label={t('backoffice_only:form_segmentation.all_users')}
                  value={false}
                  onChange={() => handleChangeType(null, onChange)}
                />
                <FormControlLabel
                  control={
                    <Radio
                      {...radioProps}
                      sx={{ ml: 1, ...radioProps?.sx }}
                    />
                  }
                  label={t('backoffice_only:form_segmentation.segment')}
                  value
                  onChange={() =>
                    handleChangeType(
                      { userSegmentation: [], groupSegmentation: [] },
                      onChange,
                    )
                  }
                />
              </RadioGroup>
            </Grid>
            {isSegmented && (
              <>
                <Grid
                  item
                  xs={6}
                >
                  <Button
                    variant="outlined"
                    sx={{ ml: 'auto', display: 'block' }}
                    onClick={() => totalUsers && showModal()}
                    disabled={!totalUsers}
                    loading={loading}
                  >
                    {t('backoffice_only:form_segmentation.segmented', {
                      count: totalUsers,
                    })}
                  </Button>
                </Grid>
                {error && (
                  <Grid
                    item
                    xs={12}
                  >
                    <Alert
                      severity="error"
                      sx={{ mb: 2 }}
                    >
                      {error.message}
                    </Alert>
                  </Grid>
                )}
                <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, ...autocompleteProps }}
                    defaultSearchOptions={autoCompleteDefaultSearchOptions}
                  />
                </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 }}
                >
                  <SegmentationItems
                    onChange={itemId =>
                      handleChange(
                        {
                          ...value,
                          groupSegmentation: addOrRemove(
                            groupSegmentation,
                            itemId,
                          ),
                        },
                        onChange,
                      )
                    }
                    selectedItems={groupSegmentation}
                    accordionSummaryProps={accordionSummaryProps}
                    useAudienceApi={useAudienceApi}
                  />
                </Grid>
              </>
            )}
          </Grid>
        );
      }}
    />
  );
};

export default FormSegmentation;
