import { useEffect, useMemo, useState } from 'react';
import { getCountries, getCountryCallingCode } from 'react-phone-number-input';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { hasFlag } from 'country-flag-icons';
import * as Flags from 'country-flag-icons/react/3x2';
import { CountryCallingCode } from 'libphonenumber-js';

import { IconChevronDown } from '@/ui/display/icon';
import { IconWorld } from '@/ui/input/constants/icons';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';

import { CountryPickerHotkeyScope } from '../types/CountryPickerHotkeyScope';

import { CountryPickerDropdownSelect } from './CountryPickerDropdownSelect';

import 'react-phone-number-input/style.css';

type StyledDropdownButtonProps = {
  isUnfolded: boolean;
};

export const StyledDropdownButtonContainer = styled.div<StyledDropdownButtonProps>`
  align-items: center;
  background: ${({ theme }) => theme.background.primary};
  border-radius: ${({ theme }) => theme.border.radius.xs};
  color: ${({ color }) => color ?? 'none'};
  cursor: pointer;
  display: flex;

  height: 32px;

  padding-left: ${({ theme }) => theme.spacing(2)};
  padding-right: ${({ theme }) => theme.spacing(2)};

  padding-right: ${({ theme }) => theme.spacing(2)};
  user-select: none;

  &:hover {
    filter: brightness(0.95);
  }
`;

const StyledIconContainer = styled.div`
  align-items: center;
  color: ${({ theme }) => theme.font.color.tertiary};
  display: flex;
  gap: ${({ theme }) => theme.spacing(1)};
  justify-content: center;

  svg {
    align-items: center;
    display: flex;
    height: 16px;
    justify-content: center;
  }
`;

export type Country = {
  countryCode: string;
  countryName: string;
  callingCode: CountryCallingCode;
  Flag: Flags.FlagComponent;
};

export const CountryPickerDropdownButton = ({
  value,
  onChange,
}: {
  value: string;
  onChange: (countryCode: string) => void;
}) => {
  const theme = useTheme();

  const [selectedCountry, setSelectedCountry] = useState<Country>();

  const { isDropdownOpen, closeDropdown } = useDropdown({
    dropdownScopeId: 'country-picker',
  });

  const handleChange = (countryCode: string) => {
    onChange(countryCode);
    closeDropdown();
  };

  const countries = useMemo<Country[]>(() => {
    const regionNamesInEnglish = new Intl.DisplayNames(['en'], {
      type: 'region',
    });

    const countryCodes = getCountries();

    return countryCodes.reduce<Country[]>((result, countryCode) => {
      const countryName = regionNamesInEnglish.of(countryCode);

      if (!countryName) return result;

      if (!hasFlag(countryCode)) return result;

      const Flag = Flags[countryCode];

      const callingCode = getCountryCallingCode(countryCode);

      result.push({
        countryCode,
        countryName,
        callingCode,
        Flag,
      });

      return result;
    }, []);
  }, []);

  useEffect(() => {
    const country = countries.find(({ countryCode }) => countryCode === value);
    if (country) {
      setSelectedCountry(country);
    }
  }, [countries, value]);

  return (
    <DropdownScope dropdownScopeId="country-picker">
      <DropdownMenu
        dropdownHotkeyScope={{ scope: CountryPickerHotkeyScope.CountryPicker }}
        clickableComponent={
          <StyledDropdownButtonContainer isUnfolded={isDropdownOpen}>
            <StyledIconContainer>
              {selectedCountry ? <selectedCountry.Flag /> : <IconWorld />}
              <IconChevronDown size={theme.icon.size.sm} />
            </StyledIconContainer>
          </StyledDropdownButtonContainer>
        }
        dropdownComponents={
          <CountryPickerDropdownSelect
            countries={countries}
            selectedCountry={selectedCountry}
            onChange={handleChange}
          />
        }
        dropdownOffset={{ x: -60, y: -34 }}
      />
    </DropdownScope>
  );
};
