import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Project from '../../model/Project';
import Query from '../../model/Query';
import UserQuery from '../../model/UserQuery';

import ProjectAPI from '../../api/ProjectAPI';
import QueryAPI from '../../api/QueryAPI';
import IDUtil from '../../util/IDUtil';
import LocalStorageHandler from '../../util/LocalStorageHandler';
import MessageHelper from "../helpers/MessageHelper";
import FlexBox from '../FlexBox';
import ProjectQueriesTable from '../workspace/projects/query/ProjectQueriesTable';
import ProjectList from "../workspace/projects/ProjectList";

class QueryEditor extends React.PureComponent {

	constructor(props) {
		super(props);
		this.state = {
            errorMessage: false,
            selectedProject: this.props.project
		};
        this.queryNameRef = React.createRef();
		this.CLASS_PREFIX = 'qed';
	}

    //communicate the result back to the owning component
    onOutput(data) {
        if(data) {
            this.setState({
                project: data.project
            })
        }
        if(this.props.onOutput) {
            this.props.onOutput(this.constructor.name, data);
        }
    }

	save = e => {
		e.preventDefault();

		// require query name value
        if(!this.queryNameRef.current.value){
            this.setState({
                errorMessage: true
            });
            return;
        }

		if(this.props.query) {
            const project = this.state.selectedProject;
			const userQuery = UserQuery.constructFromQuery(
                this.props.query,
                this.props.user.id,
                this.props.project.id,
                this.queryNameRef.current.value
            );
			QueryAPI.save(this.props.user.id, this.props.project.id, userQuery, savedQuery => {
                if(savedQuery){
                    this.props.project.queries.push({
                        name : savedQuery.name,
                        id: savedQuery.id,
                        query : savedQuery.query
                    });
                    this.onOutput({project : this.props.project, queryName: savedQuery.name});
                    //update in local storage too
                    LocalStorageHandler.storeJSONInLocalStorage(
								'stored-active-project',
								this.props.project.toLocalStorageObject()
							);
                } else {
                    alert('An error occurred while saving this query');
                    this.onOutput(null);
                }
            });
		} else { //this should never happen though
            alert('An error occurred while saving this query');
			this.onOutput(null);
		}
	};

    onSelectProject = project => {
        if(project && project.name) {
            this.setState({
                selectedProject: project
            })
        }
    };

    //----------------------------- RENDER FUNCTIONS -------------------------------

    renderValidationFailed = () => {
        return (
            <div className={IDUtil.cssClassName('validation-error', this.CLASS_PREFIX)}>
               Please name the query before saving it.
            </div>
        );
    };

    renderProjectList = (activeProject, userProjects, user, onSelectProject) => (
        <ProjectList
            buttonText="Set active project"
            activeProject={activeProject}
            onSelect={onSelectProject}
            projects={userProjects}
            user={user}
            projectIcon={true}
        />
    );

    renderQueryForm = errorMessage => {
        return (
            <form onSubmit={this.save}>
                <input type="text" ref={this.queryNameRef} placeholder="Name your query"/>
                <button type="submit" className="btn btn-light">Save</button>
                {errorMessage ? this.renderValidationFailed() : null}
            </form>
        );
    };

    renderQueryDetails = (query, collectionConfig) => (
        <div className={IDUtil.cssClassName('query-params', this.CLASS_PREFIX)}>
            {MessageHelper.renderQuery(query, collectionConfig)}
        </div>
    );

    renderQueryTable = (project, user) => {
        if(project === null || project.queries.length === 0) {
            return null;
        }

        return (
            <FlexBox isVisible={false} title={'Other queries saved in: ' + project.name}>
                <div className={[
                    IDUtil.cssClassName('no-bootstrap-custom-styling'),
                    IDUtil.cssClassName('table', this.CLASS_PREFIX)].join(' ')
                }>
                    <ProjectQueriesTable project={project} user={user}/>
                </div>
            </FlexBox>
        );
    };

	render() {
        const projectList = this.renderProjectList(
            this.state.selectedProject,
            this.props.userProjects,
            this.props.user,
            this.onSelectProject
        );
        const queryForm = this.state.selectedProject ? this.renderQueryForm(this.state.errorMessage): null;

        const queryDetails = this.state.selectedProject ?
            this.renderQueryDetails(
                this.props.query,
                this.props.collectionConfig
            ) : null;

		const queryTable = this.state.selectedProject ?
            this.renderQueryTable(this.state.selectedProject, this.props.user) :
            null
        ;

        return (
			<div className={IDUtil.cssClassName('query-editor')}>
                <div
                    title={this.state.selectedProject ? "Current user project. Click to change." : ""}
                    style={{float: this.state.selectedProject ? 'right' : 'none'}}
                >
                    {projectList}
                </div>
				{queryForm}
                {queryDetails}
				{queryTable}
			</div>
		)
	}

}

QueryEditor.propTypes = {
    // current user object used for defining access roles per project
    user: PropTypes.shape({
        id: PropTypes.string.isRequired,
        name: PropTypes.string,
        attributes: PropTypes.shape({
            allowPersonalCollections: PropTypes.bool
        })
    }),
    userProjects : PropTypes.array,
    project: Project.getPropTypes(false),
    collectionConfig : PropTypes.object.isRequired,
    query: PropTypes.object.isRequired,
    onOutput: PropTypes.func.isRequired
};

export default QueryEditor;
