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

import { maxBy } from 'lodash-es';
import HelpOutlineIcon from '@material-hu/icons/material/HelpOutline';
import Checkbox from '@material-hu/mui/Checkbox';
import Chip from '@material-hu/mui/Chip';
import Divider from '@material-hu/mui/Divider';
import FormControl, {
  type FormControlProps,
} from '@material-hu/mui/FormControl';
import FormHelperText from '@material-hu/mui/FormHelperText';
import InputLabel from '@material-hu/mui/InputLabel';
import MenuItem from '@material-hu/mui/MenuItem';
import Select, { type SelectProps } from '@material-hu/mui/Select';
import Stack from '@material-hu/mui/Stack';
import Tooltip from '@material-hu/mui/Tooltip';

import { addOrRemove } from 'src/utils/arrayUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import CircularProgress from 'src/components/CircularProgress';

type Props = {
  rules?: ControllerProps['rules'];
  name: string;
  label?: string;
  options: {
    label: string;
    value: any;
  }[];
  selectProps?: SelectProps;
  formControlProps?: FormControlProps;
  loading?: boolean;
  clearable?: boolean;
  adaptWidthToOptions?: boolean;
  limitTags?: number;
};

function FormSelectPDF({
  name,
  rules,
  label,
  options,
  selectProps,
  formControlProps,
  loading = false,
  clearable = false,
  adaptWidthToOptions = false,
  limitTags = 5,
}: Props) {
  const { control, setValue } = useFormContext();
  const { t } = useLokaliseTranslation('backoffice_only');

  const customFormControlSxProp = {
    width: adaptWidthToOptions
      ? `${(maxBy(options, option => option.label.length)?.label.length ?? 0) + 7}ch`
      : undefined,
    ...formControlProps?.sx,
  };

  return (
    <FormControl
      {...formControlProps}
      sx={customFormControlSxProp}
    >
      <Controller
        control={control}
        name={name}
        rules={rules}
        render={({ field: { ref, ...field }, fieldState: { error } }) => (
          <>
            <InputLabel color={error ? 'error' : 'primary'}>{label}</InputLabel>
            <Select
              label={label}
              {...field}
              defaultValue={field.value}
              IconComponent={
                loading
                  ? () => (
                      <CircularProgress
                        centered
                        size={15}
                        sx={{ mr: 2 }}
                      />
                    )
                  : undefined
              }
              error={!!error}
              MenuProps={{ PaperProps: { sx: { maxHeight: 500 } } }}
              renderValue={
                selectProps?.multiple
                  ? (selected: any[]) => {
                      const limitedSelected = selected.slice(0, limitTags);
                      const more = selected.length - limitedSelected.length;
                      return (
                        <Stack
                          direction="row"
                          sx={{
                            flexWrap: 'wrap',
                            gap: 0.5,
                            alignItems: 'center',
                            maxHeight: '200px',
                          }}
                        >
                          {limitedSelected.map(ls => (
                            <Chip
                              key={ls}
                              label={
                                options.find(o => o.value === ls)?.label ?? ''
                              }
                              onDelete={() => {
                                setValue(name, addOrRemove(selected, ls), {
                                  shouldDirty: true,
                                  shouldValidate: true,
                                });
                              }}
                              onMouseDown={event => {
                                event.stopPropagation();
                              }}
                            />
                          ))}
                          {more ? `+${more}` : null}
                        </Stack>
                      );
                    }
                  : undefined
              }
              {...selectProps}
              inputRef={ref}
            >
              {clearable && (
                <MenuItem value="">
                  <em>{t('backoffice_only:form_pdf_fields.none')}</em>
                </MenuItem>
              )}
              <Stack
                my={0.5}
                direction="row"
                alignItems="center"
                justifyContent="space-between"
              >
                <Divider sx={{ width: 30 }} />
                <Chip
                  key={0}
                  label={t('backoffice_only:form_pdf_fields.general')}
                  sx={{ width: 130 }}
                />
                <Divider sx={{ width: 30 }} />
              </Stack>
              <MenuItem value="COMPLETION_DATE">
                {field.value === 'COMPLETION_DATE' ? (
                  t('backoffice_only:form_pdf_fields.completion_date')
                ) : (
                  <Tooltip
                    title={t(
                      'backoffice_only:form_pdf_fields.completion_date_tooltip',
                    )}
                    placement="right"
                    arrow
                  >
                    <Stack
                      direction="row"
                      alignItems="center"
                    >
                      {t('backoffice_only:form_pdf_fields.completion_date')}
                      <HelpOutlineIcon
                        fontSize="small"
                        sx={{ ml: 1, pt: '2px' }}
                      />
                    </Stack>
                  </Tooltip>
                )}
              </MenuItem>
              <Stack
                my={0.5}
                direction="row"
                alignItems="center"
                justifyContent="space-between"
              >
                <Divider sx={{ width: 30 }} />
                <Chip
                  key={0}
                  label={t('backoffice_only:form_pdf_fields.user_profile')}
                  sx={{ width: 130 }}
                />
                <Divider sx={{ width: 30 }} />
              </Stack>
              {options.map(option => (
                <MenuItem
                  value={option.value}
                  key={option.value}
                >
                  {selectProps?.multiple && (
                    <Checkbox checked={field.value.includes(option.value)} />
                  )}
                  {option.label}
                </MenuItem>
              ))}
            </Select>
            {error && <FormHelperText error>{error?.message}</FormHelperText>}
          </>
        )}
      />
    </FormControl>
  );
}

export default FormSelectPDF;
