/**
 * Select with paginated options dropdown
 *
 * @author: Denis Makarov
 * @date: 2020-10-07
 */

import React from 'react';
import {IOption, Select, Value} from '..';
import {SIZE} from '../../constants';
import {PaginatedOptionsList} from './PaginatedOptionsList';

export interface ISelectPaginatedProps {
    isOpen?: boolean;
    isDefaultOpen?: boolean;
    isReadOnly?: boolean;
    value?: string;
    displayValue?: string;
    onSearch: (searchText: string) => void;
    size?: SIZE;
    options: IOption [];
    goToPage: (pageNum: number) => void;
    pagesCount: number;
    onSelect: (value: IOption | null) => void;
    onClose?: () => void;
    dropdownAutoWidth?: boolean;
    allowClear?: boolean;
    errorMessage?: string;
    autoFocus?: boolean;
    closeOnBlur?: boolean;
    closeOnSelect?: boolean;
    isWaiting?: boolean;
    showUnsetOption?: boolean;
    unsetText?: string;
    page: number;
}

interface IState {
    isDropdownOpen: boolean;
    searchText: string | null;
}

const defaultProps = {
    isOpen: false,
    inputSize: SIZE.MIDDLE,
    allowClear: true,
    closeOnBlur: true,
    closeOnSelect: true,
    autoFocus: false,
    dropdownAutoWidth: false
};

export class SelectPaginated extends React.PureComponent<ISelectPaginatedProps, IState> {
    static defaultProps = defaultProps;

    override state: IState;

    constructor (props: ISelectPaginatedProps) {
        super(props);

        this.state = {
            isDropdownOpen: this.props.isOpen || false,
            searchText: null
        };
    }

    openCloseDropdown = (isVisible: boolean) => {
        this.setState({isDropdownOpen: isVisible});
    };

    onSearch = (searchText: string) => {
        this.setState({searchText});
        this.props.onSearch(searchText);
    }

    onDropdownClose = () => {
        if (this.props.closeOnBlur) {
            this.setState({isDropdownOpen: false, searchText: null});

            if (this.props.onClose) {
                this.props.onClose();
            }
        }
    };

    onChange = (value: Value | undefined) => {
        if (!value) {
            this.props.onSelect(null);
        }
    }

    onSelect = (option: IOption | null) => {
        this.props.onSelect(option);

        if (this.props.closeOnSelect) {
            this.onDropdownClose();
        }
    };

    renderDropDown = () => {
        return (
            <PaginatedOptionsList
                goToPage={this.props.goToPage}
                onSelect={this.onSelect}
                options={this.props.options}
                page={this.props.page}
                pagesCount={this.props.pagesCount}
            />
        );
    }

    override render () {
        const currentOption = this.props.options.find((option) => {
            return option.value === this.props.value;
        });

        const hasError = Boolean(this.props.errorMessage);
        const placeholder: string | undefined = currentOption ? currentOption.title : this.props.displayValue;

        return (
            <Select
                isOpen={this.state.isDropdownOpen}
                isDefaultOpen={this.props.isDefaultOpen}
                options={this.props.options}
                value={this.props.value}
                onBlur={this.onDropdownClose}
                onDropdownVisibleChange={this.openCloseDropdown}
                placeholder={placeholder}
                onChange={this.onChange}
                size={this.props.size}
                allowClear={this.props.allowClear}
                showSearch={true}
                isReadOnly={this.props.isReadOnly}
                onSearch={this.onSearch}
                dropdownRender={this.renderDropDown}
                hasError={hasError}
                errorMessage={this.props.errorMessage}
                dropdownMatchSelectWidth={this.props.dropdownAutoWidth ? undefined : 'autoContent'}
                isWaiting={this.props.isWaiting}
                autoFocus={this.props.autoFocus}
            />
        );
    }
}
