import { useMemo, useState } from 'react';
import { Box, MenuItem, Select, Typography, SelectProps, TextField, SxProps } from '@mui/material';
import { FlagEmoji, defaultCountries, parseCountry } from 'react-international-phone';
import type { CountryIso2 } from 'react-international-phone';
import { ParsedCountry } from 'react-international-phone/build/types';
import ArrowDownwardIcon from '@arcblock/icons/lib/ArrowDown';
import { mergeSx } from '../Util/style';

export interface CountryDisplayOptions {
  hideFlag?: boolean;
  hideDialCode?: boolean;
}

export interface CountrySelectProps<T extends keyof ParsedCountry = 'iso2'>
  extends Omit<SelectProps, 'value' | 'onChange'> {
  value: T extends 'iso2' ? CountryIso2 : string;
  onChange?: (value: T extends 'iso2' ? CountryIso2 : string) => void;
  selectCountryProps?: CountryDisplayOptions;
  preview?: boolean;
  valueField?: T;
}

// 定义组件类型
type CountrySelectComponent = <T extends keyof ParsedCountry = 'iso2'>(
  props: CountrySelectProps<T> & { ref?: React.ForwardedRef<HTMLDivElement> }
) => React.ReactElement<any>;

// 实现组件
function CountrySelectInner<T extends keyof ParsedCountry = 'iso2'>({
  ref = undefined,
  value,
  onChange = undefined,
  sx = {},
  selectCountryProps = undefined,
  preview = false,
  valueField = 'iso2' as T,
  ...rest
}: CountrySelectProps<T> & {
  ref?: React.Ref<unknown>;
}) {
  const { hideFlag = true, hideDialCode = false } = selectCountryProps || {};
  const [searchQuery, setSearchQuery] = useState('');

  const countryDetail = useMemo(() => {
    const item = defaultCountries.find((v) => v[1] === value);
    return value && item ? parseCountry(item) : { name: '', iso2: '', dialCode: '' };
  }, [value]);

  const filteredCountries = useMemo(() => {
    if (!searchQuery) return defaultCountries;

    const query = searchQuery.toLowerCase();
    return defaultCountries.filter((country) => {
      const parsed = parseCountry(country);
      return (
        parsed.name.toLowerCase().includes(query) ||
        parsed.iso2.toLowerCase().includes(query) ||
        parsed.dialCode.includes(query)
      );
    });
  }, [searchQuery]);

  const renderCountryContent = (
    <Box
      sx={{
        display: 'flex',
        alignItems: 'center',
        flexWrap: 'nowrap',
        gap: 0.5,
        cursor: preview ? 'default' : 'pointer',
      }}>
      {hideFlag ? null : <FlagEmoji iso2={value} style={{ display: 'flex', width: 24, color: 'inherit' }} />}
      <Typography component="span" sx={{ lineHeight: 1.5 }}>
        {hideDialCode ? countryDetail?.name : `+${countryDetail?.dialCode}`}
      </Typography>
    </Box>
  );

  if (preview) {
    return renderCountryContent;
  }

  return (
    <Select
      {...rest}
      ref={ref}
      MenuProps={{
        style: { maxHeight: 400, top: 2, zIndex: 9999 }, // 默认 zIndex 为 1300, 但是在 SwipeableDrawer 中需要设置为 9999
        anchorOrigin: { vertical: 'bottom', horizontal: 'left' },
        transformOrigin: { vertical: 'top', horizontal: 'left' },
        ...(rest.MenuProps ?? {}),
      }}
      sx={mergeSx(
        {
          '&.Mui-focused:has(div[aria-expanded="false"])': { fieldset: { display: 'block' } },
          '.MuiSelect-select': { padding: 1, paddingRight: '24px !important' },
          svg: { right: 4, top: 10 },
          '&:hover': {
            'fieldset.MuiOutlinedInput-notchedOutline': {
              borderColor: 'divider',
            },
          },
          'fieldset.MuiOutlinedInput-notchedOutline': {
            borderColor: 'divider',
          },
          '.MuiMenuItem-root': { justifyContent: 'flex-start' },
        },
        sx as SxProps
      )}
      value={value}
      onChange={(e) => onChange?.(e.target.value as T extends 'iso2' ? CountryIso2 : string)}
      // eslint-disable-next-line react/no-unstable-nested-components
      IconComponent={(props) => <ArrowDownwardIcon {...props} width={20} height={20} />}
      renderValue={() => renderCountryContent}>
      <Box sx={{ p: 1, position: 'sticky', top: 0, bgcolor: 'background.paper', zIndex: 1 }}>
        <TextField
          size="small"
          fullWidth
          placeholder="Search country..."
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          onClick={(e) => e.stopPropagation()}
          onKeyDown={(e) => e.stopPropagation()}
        />
      </Box>
      {filteredCountries.map((c) => {
        const parsed = parseCountry(c);
        return (
          <MenuItem key={parsed.iso2} value={parsed[valueField]}>
            {hideFlag ? null : <FlagEmoji iso2={parsed.iso2} style={{ marginRight: 8, width: 24 }} />}
            <Typography
              sx={{
                marginRight: 1,
              }}>
              {parsed.name}
            </Typography>
            {hideDialCode ? null : <Typography color="gray">(+{parsed.dialCode})</Typography>}
          </MenuItem>
        );
      })}
    </Select>
  );
}

// 正确导出泛型组件
const CountrySelect = CountrySelectInner as CountrySelectComponent;

export default CountrySelect;
