import type { FC } from 'react';
import React, { useState } from 'react';
import { Dropdown } from '@theorchard/suite-components';
import { orderBy } from 'lodash';
import stringSimilarity from 'string-similarity';
import type { DropdownOption } from 'src/types';

const CLASSNAME = 'CountryNameDropdown';

export interface DropDownCountryItem {
    name: string;
    code: string;
}

const createOption = (
    country: DropDownCountryItem
): DropdownOption<DropDownCountryItem> => ({
    label: country.name,
    value: country.code,
    data: country,
});

interface Props {
    selectedCountry?: string;
    countries: DropDownCountryItem[];
    loading: boolean;
    onChange: (countryCode?: string) => void;
    placeholder: string;
}

const CountryNameDropdown: FC<Props> = ({
    selectedCountry,
    countries,
    loading,
    onChange,
    placeholder,
}) => {
    const [selectedValue, setSelectedValue] = useState<string | undefined>(
        selectedCountry
    );

    const options = orderBy(
        [...countries.map(createOption)],
        ['label'],
        ['asc']
    );

    const handleChange = (
        value: DropdownOption<DropDownCountryItem> | null
    ) => {
        setSelectedValue(value?.data?.code);
        onChange(value?.data?.code ?? undefined);
    };

    return (
        <Dropdown
            className={CLASSNAME}
            options={options}
            isLoading={loading}
            selectedValue={selectedValue}
            onChange={handleChange}
            isClearable
            filterOption={(dropDownValue, inputValue) => {
                if (inputValue && inputValue.length >= 2) {
                    const country = dropDownValue.label.toLowerCase();
                    const similarities = stringSimilarity.findBestMatch(
                        inputValue.toLowerCase(),
                        [dropDownValue.label.toLowerCase()]
                    );
                    let match = false;
                    const splitCountryWords = country.split(' ');

                    splitCountryWords.forEach(c => {
                        if (c.startsWith(inputValue.toLowerCase())) {
                            match = true;
                        }
                    });

                    if (!match) return similarities.bestMatch.rating > 0.6;

                    return match;
                }
                return true;
            }}
            placeholder={placeholder}
        />
    );
};

export default CountryNameDropdown;
