import React, { useMemo } from 'react';
import cx from 'classnames';
import { Select } from '../select';
import { t } from './i18n';
import {
    createCountryOptions,
    createCountryOptionFromCode,
    createFlatCountryOptions,
} from './utils';
import type { CountryInfo, CountryOption } from './types';
import type { SelectProps } from '../select';

const CLASSNAME = 'SuiteCountrySelect';

export interface CountrySelectProps<T extends CountryOption = CountryOption>
    extends Omit<SelectProps<T>, 'options' | 'initialValue' | 'selectedValue'> {
    /**
     * The selected country on first render.
     */
    initialValue?: string;

    /**
     * The selected country.
     * Note when you use this property you are using the component in "controlled" mode.
     * Meaning you need to handle onChange events and manage state yourself.
     */
    selectedValue?: string;

    /**
     * Custom list of countries to use.
     */
    countries?: CountryInfo[] | string[];

    /**
     * Adds a global option to the top of the list with the code 'WW'
     */
    includeGlobal?: boolean;
}

/**
 * CountrySelect provides a list of countries and allows user to select a single one from the list.
 *
 * @type molecule
 * @status live
 * @tags form-elements, selects
 */
export function CountrySelect({
    placeholder = t('selectCountry'),
    menuMinWidth = 469,
    optionTagMaxWidth = 150,
    menuWidth = 530,
    className,
    testId = CLASSNAME,
    onListModeChange,
    initialValue: initialCountry,
    selectedValue: selectedCountry,
    countries,
    filterPlaceholder = t('searchCountry'),
    includeGlobal = false,
    ...props
}: CountrySelectProps) {
    const options = useMemo(
        () =>
            countries ? createCountryOptions(countries) : createFlatCountryOptions(includeGlobal),
        [countries, includeGlobal]
    );

    const initialValue = useMemo(
        () => initialCountry && createCountryOptionFromCode(initialCountry),
        [initialCountry]
    );

    const selectedValue = useMemo(
        () => selectedCountry && createCountryOptionFromCode(selectedCountry),
        [selectedCountry]
    );

    return (
        <Select
            {...props}
            initialValue={initialValue}
            selectedValue={selectedValue}
            placeholder={placeholder}
            filterPlaceholder={filterPlaceholder}
            className={cx(CLASSNAME, className)}
            testId={testId}
            options={options}
            menuMinWidth={menuMinWidth}
            menuWidth={menuWidth}
            optionTagMaxWidth={optionTagMaxWidth}
        />
    );
}
