import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
import {
  type FieldValues,
  useController,
  useFormContext,
} from 'react-hook-form';

import {
  IconChevronDown,
  IconChevronLeft,
  IconChevronRight,
  IconExclamationCircle,
} from '@material-hu/icons/tabler';
import Collapse from '@material-hu/mui/Collapse';
import Divider from '@material-hu/mui/Divider';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuList from '@material-hu/components/design-system/List';
import HuListItem from '@material-hu/components/design-system/List/components/ListItem';
import HuMenu from '@material-hu/components/design-system/Menu';
import HuSkeleton from '@material-hu/components/design-system/Skeleton';
import HuTitle from '@material-hu/components/design-system/Title';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import { type SegmentationType } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  dynamicPrefix,
  RequestField,
  segmentationPrefix,
  UserGeneralFieldsIds,
} from 'src/components/Condition/components/constants';

import { type HuMenuItem, type MenuSelectProps } from '.';

type FieldSelectProps = MenuSelectProps & {
  segmentationGroups?: SegmentationType[];
};

const FieldSelect = ({
  title,
  items,
  categorizedItems,
  segmentationGroups,
  name,
  isLoading,
  isDisabled,
  onChange,
  rules,
}: FieldSelectProps) => {
  const { t } = useLokaliseTranslation([
    'workflows',
    'general',
    'backoffice_only',
  ]);
  const { control } = useFormContext();
  const { field, fieldState } = useController<FieldValues, string>({
    control,
    name,
    defaultValue: undefined,
    rules: rules || {},
  });
  const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);
  const [isTruncated, setIsTruncated] = useState(false);
  const [profileSearch, setProfileSearch] = useState('');
  const [segmentationSearch, setSegmentationSearch] = useState('');

  const getSelectedIds = () => {
    return field.value ? [field.value] : [];
  };

  const selectedIds = getSelectedIds();

  const segmentationItems: HuMenuItem[] = useMemo(
    () =>
      (segmentationGroups || []).map(group => ({
        id: `${segmentationPrefix}${group.id}`,
        label: group.name,
      })),
    [segmentationGroups],
  );

  const allItems =
    items
      ?.concat(categorizedItems?.flatMap(cat => cat.items) || [])
      .concat(segmentationItems) || [];
  const selectedItem = allItems?.find(item => selectedIds.includes(item?.id));

  const handleMenuItemClick = (optionId: HuMenuItem['id']) => {
    const newValue = selectedIds.includes(optionId) ? null : optionId;
    setAnchorElement(null);
    field.onChange(newValue);
    onChange?.(allItems.filter(item => item.id === newValue));
  };

  const getDisplayText = () => {
    if (!selectedItem) return title;
    return selectedItem.label;
  };

  const getDefaultSubMenu = useCallback((): number => {
    if (!field?.value) return 0;
    if (Object.values(RequestField).includes(field.value)) return 1;
    if (
      Object.values(UserGeneralFieldsIds).includes(field.value) ||
      field?.value?.includes(dynamicPrefix)
    )
      return 2;
    if (
      typeof field.value === 'string' &&
      field.value.startsWith(segmentationPrefix)
    )
      return 3;
    return 0;
  }, [field?.value]);

  const [subMenu, setSubMenu] = useState<number | null>(getDefaultSubMenu());

  useEffect(() => {
    if (anchorElement) {
      setSubMenu(getDefaultSubMenu());
      setProfileSearch('');
      setSegmentationSearch('');
    }
  }, [anchorElement, getDefaultSubMenu]);

  const filteredCategorizedItems = useMemo(() => {
    if (!profileSearch) return categorizedItems;
    const lowerSearch = profileSearch.toLowerCase();
    return categorizedItems
      ?.map(category => ({
        ...category,
        items: category.items.filter(item =>
          item.label.toLowerCase().includes(lowerSearch),
        ),
      }))
      .filter(category => category.items.length > 0);
  }, [categorizedItems, profileSearch]);

  const filteredSegmentationItems = useMemo(() => {
    if (!segmentationSearch) return segmentationItems;
    const lowerSearch = segmentationSearch.toLowerCase();
    return segmentationItems.filter(item =>
      item.label.toLowerCase().includes(lowerSearch),
    );
  }, [segmentationItems, segmentationSearch]);

  if (isLoading) {
    return (
      <HuSkeleton
        variant="text"
        height={35}
        sx={{
          flex: 1,
        }}
      />
    );
  }

  const hasSegmentations = segmentationGroups && segmentationGroups.length > 0;

  return (
    <>
      <Stack
        sx={{
          flexDirection: 'row',
          alignItems: 'center',
          gap: 1,
          flex: 1,
        }}
      >
        <HuTooltip
          description={selectedItem?.label || ''}
          disableTooltip={!isTruncated}
        >
          <Button
            onClick={e => setAnchorElement(e.currentTarget)}
            variant="outlined"
            endIcon={
              <Stack
                sx={{
                  flexDirection: 'row',
                  alignItems: 'center',
                }}
              >
                <IconChevronDown size={16} />
              </Stack>
            }
            disabled={!!isDisabled}
            sx={{
              minWidth: '100%',
              maxWidth: '100px',
              width: '100%',
            }}
          >
            <Typography
              ref={el => el && setIsTruncated(el.scrollWidth > el.clientWidth)}
              variant="globalXS"
              fontWeight="semiBold"
              color={theme =>
                isDisabled
                  ? theme.palette.new.text.neutral.disabled
                  : theme.palette.new.text.neutral.brand
              }
              noWrap
            >
              {getDisplayText()}
            </Typography>
          </Button>
        </HuTooltip>
        {fieldState?.error && (
          <HuTooltip
            title={fieldState.error.message}
            direction="top"
          >
            <IconExclamationCircle
              color="error"
              size={16}
            />
          </HuTooltip>
        )}
      </Stack>
      <HuMenu
        open={!!anchorElement}
        onClose={() => setAnchorElement(null)}
        anchorEl={anchorElement}
        position="left"
        sx={{
          '& .MuiPaper-root': {
            overflow: 'hidden',
            maxHeight: 'none',
          },
          '& .MuiList-root': {
            overflow: 'visible',
            maxHeight: 'none',
          },
        }}
      >
        <Stack sx={{ width: 300 }}>
          <Collapse
            in={subMenu === 0}
            timeout={200}
          >
            <HuList>
              <HuListItem
                onClick={() => setSubMenu(1)}
                text={{
                  title: t('workflows:request_fields'),
                }}
                action={{
                  onClick: () => setSubMenu(1),
                  Icon: IconChevronRight,
                }}
                sx={{
                  '& .MuiTypography-root': {
                    fontWeight: 'regular',
                  },
                }}
              />
              <HuListItem
                onClick={() => setSubMenu(2)}
                text={{
                  title: t('workflows:profile_fields'),
                }}
                action={{
                  onClick: () => setSubMenu(2),
                  Icon: IconChevronRight,
                  color: 'inherit',
                }}
                sx={{
                  '& .MuiTypography-root': {
                    fontWeight: 'regular',
                  },
                }}
              />
              <HuListItem
                onClick={() => setSubMenu(3)}
                text={{
                  title: t('workflows:segmentations'),
                }}
                action={{
                  onClick: () => setSubMenu(3),
                  Icon: IconChevronRight,
                  color: 'inherit',
                }}
                sx={{
                  '& .MuiTypography-root': {
                    fontWeight: 'regular',
                  },
                }}
              />
            </HuList>
          </Collapse>
          {/* Request fields */}
          <Collapse
            in={subMenu === 1}
            timeout={200}
          >
            <Stack
              sx={{
                flexDirection: 'row',
                alignItems: 'center',
                px: 1,
                py: 1,
                gap: 2,
                cursor: 'pointer',
                '&:hover': {
                  backgroundColor: theme =>
                    theme.palette.new.background.elements.grey,
                },
              }}
              onClick={() => setSubMenu(0)}
            >
              <Button
                onClick={() => setSubMenu(0)}
                sx={{ p: 0, minWidth: 0 }}
              >
                <IconChevronLeft />
              </Button>
              <Typography variant="globalS">
                {t('workflows:request_fields')}
              </Typography>
            </Stack>
            <Stack sx={{ overflowY: 'auto', maxHeight: 300 }}>
              <HuList>
                {items?.map(item => (
                  <HuListItem
                    key={item.id}
                    onClick={() => handleMenuItemClick(item.id)}
                    text={{ title: item.label }}
                    selected={selectedIds.includes(item.id)}
                    sx={{
                      '& .MuiTypography-root': {
                        fontWeight: 'regular',
                      },
                    }}
                  />
                ))}
              </HuList>
            </Stack>
          </Collapse>
          {/* Profile fields */}
          <Collapse
            in={subMenu === 2}
            timeout={200}
          >
            <Stack
              sx={{
                p: 1,
                gap: 2,
                alignItems: 'center',
                flexDirection: 'row',
                cursor: 'pointer',
                '&:hover': {
                  backgroundColor: theme =>
                    theme.palette.new.background.elements.grey,
                },
              }}
              onClick={() => setSubMenu(0)}
            >
              <Button
                onClick={() => setSubMenu(0)}
                sx={{ p: 0, minWidth: 0 }}
              >
                <IconChevronLeft />
              </Button>
              <Typography variant="globalS">
                {t('workflows:profile_fields')}
              </Typography>
            </Stack>
            <Stack sx={{ px: 1, pb: 1 }}>
              <HuSearch
                placeholder={t('general:search')}
                value={profileSearch}
                onChange={setProfileSearch}
                size="small"
              />
            </Stack>
            <Stack sx={{ overflowY: 'auto', maxHeight: 300 }}>
              {filteredCategorizedItems &&
              filteredCategorizedItems.length > 0 ? (
                <HuList>
                  {filteredCategorizedItems.map((category, categoryIndex) => (
                    <Fragment key={category.label + categoryIndex}>
                      <Stack sx={{ pt: 1, gap: 1 }}>
                        <Typography
                          variant="globalXS"
                          fontWeight="semiBold"
                          color="text.secondary"
                          sx={{ px: 2 }}
                        >
                          {category.label}
                        </Typography>
                        <Divider />
                      </Stack>
                      {category.items.map(item => (
                        <HuListItem
                          key={item.id}
                          onClick={() => handleMenuItemClick(item.id)}
                          text={{ title: item.label }}
                          selected={selectedIds.includes(item.id)}
                          sx={{
                            '& .MuiTypography-root': {
                              fontWeight: 'regular',
                            },
                          }}
                        />
                      ))}
                    </Fragment>
                  ))}
                </HuList>
              ) : (
                <Stack sx={{ p: 2 }}>
                  <HuTitle
                    title={t('backoffice_only:condition.no_results')}
                    description={t(
                      'backoffice_only:condition.no_results_description',
                    )}
                    variant="S"
                  />
                </Stack>
              )}
            </Stack>
          </Collapse>
          {/* Segmentations */}
          <Collapse
            in={subMenu === 3}
            timeout={200}
          >
            <Stack
              sx={{
                p: 1,
                gap: 2,
                alignItems: 'center',
                flexDirection: 'row',
                cursor: 'pointer',
                '&:hover': {
                  backgroundColor: theme =>
                    theme.palette.new.background.elements.grey,
                },
              }}
              onClick={() => setSubMenu(0)}
            >
              <Button
                onClick={() => setSubMenu(0)}
                sx={{ p: 0, minWidth: 0 }}
              >
                <IconChevronLeft />
              </Button>
              <Typography variant="globalS">
                {t('workflows:segmentations')}
              </Typography>
            </Stack>
            {hasSegmentations && (
              <Stack sx={{ px: 1, pb: 1 }}>
                <HuSearch
                  placeholder={t('general:search')}
                  value={segmentationSearch}
                  onChange={setSegmentationSearch}
                  size="small"
                />
              </Stack>
            )}
            <Stack sx={{ overflowY: 'auto', maxHeight: 300 }}>
              {!hasSegmentations && (
                <Stack sx={{ p: 2, gap: 0.5 }}>
                  <Typography
                    variant="globalS"
                    fontWeight="semiBold"
                  >
                    {t('workflows:no_segmentations')}
                  </Typography>
                  <Typography
                    variant="globalXS"
                    color="text.secondary"
                  >
                    {t('workflows:no_segmentations_description')}
                  </Typography>
                </Stack>
              )}
              {hasSegmentations && filteredSegmentationItems.length === 0 && (
                <Stack sx={{ p: 2 }}>
                  <HuTitle
                    title={t('backoffice_only:condition.no_results')}
                    description={t(
                      'backoffice_only:condition.no_results_description',
                    )}
                    variant="S"
                  />
                </Stack>
              )}
              {hasSegmentations && filteredSegmentationItems.length > 0 && (
                <HuList>
                  {filteredSegmentationItems.map(item => (
                    <HuListItem
                      key={item.id}
                      onClick={() => handleMenuItemClick(item.id)}
                      text={{ title: item.label }}
                      selected={selectedIds.includes(item.id)}
                      sx={{
                        '& .MuiTypography-root': {
                          fontWeight: 'regular',
                        },
                      }}
                    />
                  ))}
                </HuList>
              )}
            </Stack>
          </Collapse>
        </Stack>
      </HuMenu>
    </>
  );
};

export default FieldSelect;
