/**
 * Component Transfer - double column transfer choice box
 *
 * @author Brauer Ilya
 * @date 2021-02-24
 */
import * as React from 'react';
import {Button, CardPanel, INTENT, IOption, OptionList} from '../../index';

import * as styles from './transfer.m.scss';

interface IProps {
    defaultLeftOptions: IOption[];
    defaultRightOptions: IOption[];
    leftTitle: React.ReactNode;
    rightTitle: React.ReactNode;
    onMove: () => void;
    optionRenderer?: (option: IOption) => React.ReactNode;
}

interface IState {
    leftOptions: IOption[];
    rightOptions: IOption[];
    selectedLeft: string[];
    selectedRight: string[];
}

export class Transfer extends React.PureComponent<IProps, IState> {

    override state: IState = {
        leftOptions: this.props.defaultLeftOptions,
        rightOptions: this.props.defaultRightOptions,
        selectedLeft: [],
        selectedRight: []
    };

    get leftValues () {
        return this.state.leftOptions.map((option) => option.value.toString());
    }

    get rightValues () {
        return this.state.rightOptions.map((option) => option.value.toString());
    }

    handleSelect = (type: 'left' | 'right') => (option: IOption) => {
        this.setState((prevState) => {
            const selectedList = type === 'left' ? prevState.selectedLeft : prevState.selectedRight;

            let newList: string[] = [];

            if (selectedList.includes(option.value.toString())) {
                newList = selectedList.reduce<string[]>((result, item) => {
                    if (item !== option.value.toString()) {
                        result.push(item);
                    }

                    return result;
                }, []);
            } else {
                newList = selectedList.concat(option.value.toString());
            }

            return {
                selectedLeft: type === 'left' ?  newList : prevState.selectedLeft,
                selectedRight: type === 'right' ? newList : prevState.selectedRight
            };
        });
    };

    moveToRight = () => {
        this.setState((prevState) => {
            const newLeft: IOption[] = [];
            const newRight = prevState.rightOptions.slice();

            prevState.leftOptions.forEach((leftOption) => {
                if (prevState.selectedLeft.includes(leftOption.value.toString())) {
                    newRight.push(leftOption);
                } else {
                    newLeft.push(leftOption);
                }
            });

            return {
                leftOptions: newLeft,
                rightOptions: newRight,
                selectedLeft: [],
                selectedRight: []
            };
        }, this.props.onMove);
    };

    moveToLeft = () => {
        this.setState((prevState) => {
            const newRight: IOption[] = [];
            const newLeft = prevState.leftOptions.slice();

            prevState.rightOptions.forEach((rightOption) => {
                if (prevState.selectedRight.includes(rightOption.value.toString())) {
                    newLeft.push(rightOption);
                } else {
                    newRight.push(rightOption);
                }
            });

            return {
                leftOptions: newLeft,
                rightOptions: newRight,
                selectedLeft: [],
                selectedRight: []
            };
        }, this.props.onMove);
    };

    override render () {
        return (
            <div className={styles.transferContainer} data-component-id={'Transfer'}>
                <div className={styles.transferItemsContainer}>
                    <CardPanel
                        title={this.props.leftTitle}
                        noBodyPadding={true}
                        isWide={true}
                    >
                        <OptionList
                            value={this.state.selectedLeft}
                            options={this.state.leftOptions}
                            onSelect={this.handleSelect('left')}
                            forwardRef={{current: null}}
                            optionRenderer={this.props.optionRenderer}
                        />
                    </CardPanel>
                </div>

                <div className={styles.buttons}>
                    <Button
                        leftIcon={'chevron-right'}
                        onClick={this.moveToRight}
                        isDisabled={this.state.selectedLeft.length === 0}
                        intent={INTENT.PRIMARY}
                    />
                    <br/>
                    <br/>
                    <Button
                        leftIcon={'chevron-left'}
                        onClick={this.moveToLeft}
                        isDisabled={this.state.selectedRight.length === 0}
                        intent={INTENT.PRIMARY}
                    />
                </div>

                <div className={styles.transferItemsContainer}>
                    <CardPanel
                        title={this.props.rightTitle}
                        noBodyPadding={true}
                        isWide={true}
                    >
                        <OptionList
                            value={this.state.selectedRight}
                            options={this.state.rightOptions}
                            onSelect={this.handleSelect('right')}
                            forwardRef={{current: null}}
                            optionRenderer={this.props.optionRenderer}
                        />
                    </CardPanel>
                </div>
            </div>
        );
    }
}
