import IDUtil from '../../util/IDUtil';
import ComponentUtil from '../../util/ComponentUtil';
import FlexModal from '../FlexModal';

import FieldCategoryCreator from './FieldCategoryCreator';

import ReactTooltip from 'react-tooltip'; //https://www.npmjs.com/package/react-tooltip
import { PowerSelectMultiple } from 'react-power-select';

export default class FieldCategorySelector extends React.Component {

	constructor(props) {
		super(props);

		this.state = {
			showModal : false
		};
		this.CLASS_PREFIX = 'fcs';
	}

	onComponentOutput = (componentClass, data) => {
		if(componentClass === 'FieldCategoryCreator') {
			this.onFieldsSelected(data);
		}
	};

	onOutput(data) {
		if(this.props.onOutput) {
			if(data !== null) {
                this.props.onOutput(this.constructor.name, data);
			} else {
                this.props.onOutput(this.constructor.name, null);
            }
		}
	}

    handleChange ({ options }) {
    	let found = false;
    	const tmp = {};
    	for(let i=0;i<options.length;i++) {
    		const fc = options[i];
    		if(tmp[fc.id]) {
    			found = true;
    			break;
    		}
    		tmp[fc.id] = true;
    	}
		if(!found) {
			this.onOutput(options);
	    }
    }

    isSelected(selection, selectedFields) {
    	let selected = false;
    	for(let i=0;i<selectedFields.length;i++) {
    		if(selectedFields[i].id === selection.id){
    			selected = true;
    			break;
    		}
    	}
    	return selected;
    }

    onFieldsSelected(data) {
    	ComponentUtil.hideModal(this, 'showBookmarkModal', 'fields__modal', true, () => {
    		const fields = this.props.fieldCategory || [];
    		if(data) { //when nothing was selected, it is no use to update the owner
	    		fields.push(data);
	    		this.onOutput(fields)
	    	}
    	});
    }

    addCustomFields(selectComponent) {
    	selectComponent.actions.close();
    	this.setState({
    		showModal : true
    	})
    }

    removeEnrichmentFields(fieldCategories, allTextFields) {
        const fieldsToIgnore =  [...fieldCategories.filter(el => el.enrichment)].map(i => i.fields).flat();
        return fieldsToIgnore.length ? fieldsToIgnore.map(
            ignoreItem => allTextFields.indexOf(ignoreItem) !== -1 ?
                allTextFields.filter(e => e !== ignoreItem)
                : null
            ).flat() :
            null
        ;
    }

    getGroupedOptions(fieldCategories, selectedFields) {
        const optsMetadata = [];
        const optsEnrichment = [];
        const optionsToSelect = fieldCategories.filter(fc => !this.isSelected(fc, selectedFields));
        optionsToSelect.forEach(fc => {
            if (fc.enrichment) {
                optsEnrichment.push(fc)
            } else {
                optsMetadata.push(fc)
            }
        });
        if (optsEnrichment.length && optsMetadata.length) {
            return [{"label": "── Archive's metadata ──", "options": optsMetadata},
                {"label": "── Enrichments ──", "options": optsEnrichment}]
        } else if (optsMetadata.length) {
            return [{"label": "── Archive's metadata ──", "options": optsMetadata}]
        } else if (optsEnrichment.length) {
            return [{"label": "── Enrichments ──", "options": optsEnrichment}]
        } else {
            return [];
        }
    }

    renderSelectionModal = (fcCreatorData, fcCreatorCallback) => {
        return (
            <FlexModal
                size="large"
                elementId="fields__modal"
                stateVariable="showModal"
                owner={this}
                title="Create a new cluster of metadata fields to narrow down search">
                <FieldCategoryCreator data={fcCreatorData} onOutput={fcCreatorCallback}/>
            </FlexModal>
        );
    };

    renderSelector = (queryId, collectionConfig, groupedOptions, selectedFields) => {
        return (
            <PowerSelectMultiple
                key={'__pwsm__' + queryId}
                options={groupedOptions}
                selected={selectedFields}
                optionLabelPath="label"
                optionComponent={
                    <ListOption collectionConfig={collectionConfig}/>
                }
                selectedOptionComponent={
                    <SelectedOption
                        queryId={queryId}
                        collectionConfig={collectionConfig}/>
                }
                onChange={this.handleChange.bind(this)}
                placeholder="All"
                afterOptionsComponent={({ select }) => (
                    <div className={IDUtil.cssClassName('option-create', this.CLASS_PREFIX)}>
                        <button className="btn btn-sm btn-primary"
                            onClick={() => {
                                this.addCustomFields(select);
                            }}>
                          + Custom field cluster
                        </button>
                    </div>
                )}
            />
        );
    }

	render() {
        const fieldCategories = this.props.collectionConfig ? this.props.collectionConfig.getMetadataFieldCategories() : null;
        const allTextFields = this.props.collectionConfig ? this.props.collectionConfig.getStringFields() : []
        const selectedFields = this.props.fieldCategory || [];

        //render the modal for creating new field clusters
        const fieldSelectionModal = this.state.showModal ? this.renderSelectionModal(
            allTextFields.map(field => (
                {'value': field, 'prettyName': this.props.collectionConfig.toPrettyFieldName(field)})
            ),
            this.onComponentOutput
        ) : null;

        //for rendering the selector
        let fieldCategorySelector = null;
		if(fieldCategories && selectedFields && allTextFields) {
            const nonEnrichedMetadata = this.removeEnrichmentFields(fieldCategories, allTextFields);
            fieldCategories.unshift({
                "id": "allMetadata",
                "label": "all metadata fields",
                "fields": nonEnrichedMetadata ? nonEnrichedMetadata : allTextFields
            });
            const groupedOptions = this.getGroupedOptions(fieldCategories, selectedFields);

			fieldCategorySelector = this.renderSelector(
                this.props.queryId,
                this.props.collectionConfig,
                groupedOptions,
                selectedFields
            );
		}

		return (
            <div className={IDUtil.cssClassName('field-category-selector')}>
                {fieldCategorySelector}
                <ReactTooltip id={'__fs__tt' + this.props.queryId} />
                {fieldSelectionModal}
            </div>
        )
	}
}

export const ListOption = ({option, collectionConfig}) => {
    return (
        <div title={
            ComponentUtil.sortArrayOfStrings( // sort prettified values and join as a new string to form the title
                option.fields.map(f => collectionConfig.toPrettyFieldName(f))
            ).join('\n')}
        >
            {option.label}
        </div>
    )
};

export const SelectedOption = ({option, queryId, collectionConfig}) => (
    <ul className="bg__ul-selectedOption">
        <li className="PowerSelectMultiple__SelectedOption">
		<span className="PowerSelectMultiple__SelectedOption__Label"
              title={option.fields.map((f) => collectionConfig.toPrettyFieldName(f)).join('\n')}>
			{option.label}
		</span>
        </li>
    </ul>
);
