import {
  Box,
  InputAdornment,
  ListItem,
  ListItemIcon,
  ListItemText,
  Menu,
  MenuItem,
  TextField,
} from '@mui/material';
import { useMemo, useRef, useState, type RefObject } from 'react';
import { ArrowDown2 } from 'iconsax-react';
import ReactCountryFlag from 'react-country-flag';
import { useTranslation } from 'react-i18next';
import { countries, type Country } from '../data/countries';
import type { CountryCode } from '@/types/commonTypes';
import { Icon } from '@rkheftan/harmony-ui';
import { LTRTypography } from '@/components/common/LTRTypography';
import { Virtuoso } from 'react-virtuoso';

interface CountryCodeSelectorProps {
  show: boolean;
  value: CountryCode;
  onChange: (newValue: CountryCode) => void;
  menuAnchor: HTMLElement | null;
  onCloseFocusRef: RefObject<HTMLInputElement | null>;
  disabled?: boolean;
}

export function CountryCodeSelector({
  show,
  value,
  onChange,
  menuAnchor,
  onCloseFocusRef,
  disabled = false,
}: CountryCodeSelectorProps) {
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  const [searchTerm, setSearchTerm] = useState('');
  const open = Boolean(anchorEl);
  const searchInputRef = useRef<HTMLInputElement>(null);
  const menuWidth = menuAnchor ? menuAnchor.clientWidth : 'auto';
  const { t, i18n } = useTranslation(['country', 'common']);

  const selectedCountry =
    countries.find((c) => c.phone === value) || countries[0];

  const handleClick = () => {
    if (disabled) return;
    setAnchorEl(menuAnchor);
  };

  const handleClose = () => {
    setTimeout(() => setAnchorEl(null), 0);
    setTimeout(() => {
      onCloseFocusRef.current?.focus();
    }, 100);
    setSearchTerm('');
  };

  const handleSelect = (country: Country) => {
    onChange(country.phone);
    handleClose();
  };

  const handleMenuEntered = () => {
    searchInputRef.current?.focus();
  };

  const filteredCountries = useMemo(
    () =>
      countries.filter(
        (country) =>
          t(country.label, { ns: 'country' })
            .toLowerCase()
            .includes(searchTerm.toLowerCase()) ||
          country.label.toLowerCase().includes(searchTerm.toLowerCase()) ||
          country.phone.includes(searchTerm),
      ),
    [searchTerm, t],
  );

  const initialIndex = Math.max(
    0,
    filteredCountries.findIndex((c) => c.phone === value),
  );

  return (
    <InputAdornment
      position={'end'}
      sx={{
        mx: 0,
      }}
    >
      <Box
        onClick={handleClick}
        sx={{
          width: show ? 'auto' : 0,
          opacity: show ? 1 : 0,
          transition: (theme) =>
            theme.transitions.create(['width', 'opacity'], {
              duration: theme.transitions.duration.standard,
            }),
          overflow: 'hidden',
          whiteSpace: 'nowrap',
          height: '100%',
          display: 'flex',
          alignItems: 'center',
          flexDirection: i18n.dir() === 'ltr' ? 'row-reverse' : 'row',
          gap: 0.25,
          pl: show ? 0.25 : 0,

          '&:hover': {
            cursor: disabled ? 'default' : 'pointer',
          },
        }}
      >
        {/* This inner Box prevents the content from being squeezed during the transition */}
        <Icon
          Component={ArrowDown2}
          color={disabled ? 'text.disabled' : undefined}
          size="medium"
          variant="Bold"
        />

        <LTRTypography
          variant="body1"
          color={disabled ? 'text.disabled' : 'text.primary'}
        >
          {value}
        </LTRTypography>

        <ReactCountryFlag
          countryCode={selectedCountry.code}
          svg
          style={{
            height: '1.5rem',
            width: '1.5rem',
            marginTop: '-2px',
            marginRight: '4px',
            opacity: disabled ? 0.4 : 1,
          }}
        />

        <Menu
          anchorEl={anchorEl}
          open={open}
          onClose={handleClose}
          slotProps={{
            paper: {
              sx: {
                width: menuWidth,
                maxHeight: '20rem',
                overflow: 'hidden',
              },
            },
            transition: { onEntered: handleMenuEntered },
          }}
          anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
          transformOrigin={{ vertical: 'top', horizontal: 'left' }}
        >
          <Box
            tabIndex={-1}
            sx={{
              position: 'sticky',
              top: 0,
              zIndex: 1,
              p: 1,
              backgroundColor: 'background.paper',
            }}
          >
            <TextField
              inputRef={searchInputRef}
              size="small"
              fullWidth
              label={t('labels.search', { ns: 'common' })}
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
            />
          </Box>

          <Box component="div" sx={{ width: '100%', height: '25rem' }}>
            {filteredCountries.length === 0 ? (
              <MenuItem disabled>
                <ListItem>
                  <ListItemText>
                    {t('messages.noResualtFound', { ns: 'common' })}
                  </ListItemText>
                </ListItem>
              </MenuItem>
            ) : (
              <Virtuoso
                style={{ height: '100%', width: '100%' }}
                data={filteredCountries}
                initialTopMostItemIndex={initialIndex}
                itemContent={(_, country) => (
                  <MenuItem
                    key={country.code}
                    selected={country.phone === value}
                    onClick={() => handleSelect(country)}
                  >
                    <ListItemIcon>
                      <ReactCountryFlag
                        countryCode={country.code}
                        svg
                        style={{ height: '1.125rem', width: '1.125rem' }}
                      />
                    </ListItemIcon>
                    <ListItemText
                      primary={t(country.label, { ns: 'country' })}
                    />
                    <LTRTypography color="text.secondary">
                      {country.phone}
                    </LTRTypography>
                  </MenuItem>
                )}
                computeItemKey={(_, c) => c.code}
              />
            )}
          </Box>
        </Menu>
      </Box>
    </InputAdornment>
  );
}
