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

import IDUtil from '../../util/IDUtil'; // for generating unique CSS classnames for this component
import ComponentUtil from '../../util/ComponentUtil';
import AnnotationAPI from '../../api/AnnotationAPI';
import BaseColumn, { COLUMN_ANNOTATIONS } from './BaseColumn';
import ColumnHeader from './ColumnHeader';
import Tabs from './Tabs';
import classNames from 'classnames';

// just demonstrating re-use of old annotation component
// import AnnotationEditor from './annotationColumn/AnnotationEditor';
import AnnotationList from './annotationColumn/AnnotationList';
import { AnnotationEvents, MSAnnotationUtil } from './AnnotationClient';
// import SegmentationControls from './annotationColumn/SegmentationControls';

import { ResourceViewerContext } from './ResourceViewerContext';
import Strings from './_Strings';

/*
	Just wiring it in such a way that it fetches its own annotations
    (also preparing for the fact that this will be a completely independent lib later on).

	This component should react to changes to:
	- selected project
	- selected annotation target (active media object or parts of that media object or pieces of selected text later on)

	The user is required for the annotation API

	Supplies the ResourceViewerContext with all current annotation data

    TODO fix editResourceAnnotation() now multiple annotations are saved
*/

export default class AnnotationColumn extends React.Component {
    static contextType = ResourceViewerContext;

    constructor(props) {
        super(props);

        // define our tabs
        this.tabs = [
            {
                id: 'my-annotations',
                title: Strings.MY_ANNOTATIONS_TITLE,
                description: Strings.MY_ANNOTATIONS_HELP,
                class: 'secondary',
                onClick: () => {
                    this.setActiveTab('my-annotations');
                }
            }
        ];

        this.state = {
            showAnnotationForm: false,
            activeTab: this.tabs[0].id,
            isBookmarked: false
        };
    }

    componentDidMount() {
        this.context.annotationClient.events.bind(
            AnnotationEvents.ON_EDIT,
            this.onEditAnnotation
        );
        this.context.annotationClient.events.bind(
            AnnotationEvents.ON_PLAY,
            this.onPlayAnnotation
        );
        this.context.annotationClient.events.bind(
            AnnotationEvents.ON_SAVE,
            this.onSaveAnnotation
        );
        this.context.annotationClient.events.bind(
            AnnotationEvents.ON_DELETE,
            this.onDeleteAnnotation
        );
        document.addEventListener('keydown', this.onKeyPressed);
    }

    componentWillUnmount() {
        this.context.annotationClient.events.unbind(
            AnnotationEvents.ON_EDIT,
            this.onEditAnnotation
        );
        this.context.annotationClient.events.unbind(
            AnnotationEvents.ON_PLAY,
            this.onPlayAnnotation
        );
        this.context.annotationClient.events.unbind(
            AnnotationEvents.ON_SAVE,
            this.onSaveAnnotation
        );
        this.context.annotationClient.events.unbind(
            AnnotationEvents.ON_DELETE,
            this.onDeleteAnnotation
        );
        document.removeEventListener('keydown', this.onKeyPressed);
    }

    onKeyPressed = e => {
        switch (e.keyCode) {
            case 69: //e
                e.shiftKey
                    ? ComponentUtil.checkFocusAndExec(this.editAnnotation) //shift+e
                    : () => {}; //do nothing
                break;

            case 65: //a
                e.shiftKey
                    ? ComponentUtil.checkFocusAndExec(
                          this.editMediaObjectAnnotation
                      ) //shift+a
                    : () => {}; //do nothing
                break;

            case 82: //r
                e.shiftKey
                    ? ComponentUtil.checkFocusAndExec(
                          this.editResourceAnnotation
                      ) //shift+r
                    : () => {}; //do nothing
                break;
        }
    };

    /* ----------------------------- COMPONENT INTERACTION FUNCTIONS ------------------------ */

    //TODO wire this up to a button (now only a shortcut key)
    editMediaObjectAnnotation = () => {
        if (!this.context.annotationClient.config.editOptions.MediaObject)
            return;

        let annotation = this.context.annotationClient.activeAnnotation;
        if (!annotation || annotation.target.type !== 'MediaObject') {
            annotation = this.context.annotationClient.newAnnotation(
                'MediaObject',
                false
            );
        }
        this.context.annotationClient.edit(annotation);
    };

    //TODO wire this up to a button (now only a shortcut key)
    editResourceAnnotation = () => {
        let annotation = this.context.annotationClient.activeAnnotation;
        if (!annotation || annotation.target.type !== 'Resource') {
            annotation = this.context.annotationClient.newAnnotation(
                'Resource',
                false
            );
        }
        this.context.annotationClient.edit(annotation);
    };

    editAnnotation = annotation => {
        this.context.annotationClient.edit(
            annotation
                ? annotation
                : this.context.annotationClient.activeAnnotation
        );
    };

    // show the annotation form (triggered via the annotationClient)
    onEditAnnotation = data => {
        if (data.annotation && data.annotation.target) {
            this.setState({
                showAnnotationForm: true
            });
        }
    };

    onDeleteAnnotation = () => {
        this.setState({ showAnnotationForm: false });
    };

    onSaveAnnotation = () => {
        this.setState({ showAnnotationForm: true });
    };

    //activates annotation & its temporal/spatial segment
    onPlayAnnotation = data => {
        //console.debug('play the segment sam (obtain the player API)');
    };

    onReloadAnnotations = annotations => {
        this.setState({ showAnnotationForm: false });
    };

    setActiveTab = activeTab => {
        this.setState({ activeTab });
    };

    toggleColumn = () => {
        this.props.onToggle(COLUMN_ANNOTATIONS);
    };

    isBookmarked(userId, project) {
        const filter = {
            'user.keyword': userId,
            motivation: 'bookmarking'
        };
        if (project) {
            filter['project'] = project.id;
        }
        AnnotationAPI.getFilteredAnnotations(
            // load all "bookmark group annotations" of current user project
            userId,
            filter,
            null, //not_filters
            () => {
                this.setState({ isBookmarked: true });
            }
        );
    }

    renderWarningList = (activeProject, isBookmarked, showBookmarkSelector) => {
        const warnings = [];

        // active project required warning
        !activeProject &&
            warnings.push(
                <div className="warning" key="project">
                    <i className="fa fa-info-circle" />
                    {Strings.ANNOTATIONS_FIRST_SELECT_PROJECT}
                </div>
            );

        // bookmark required warning, only when active project is available
        // because else the bookmark link won't work properly
        if (activeProject && !isBookmarked) {
            const parts = Strings.ANNOTATIONS_FIRST_BOOKMARK.split('%ACTION%');
            if (parts.length < 2) {
                console.error(
                    'ANNOTATIONS_FIRST_BOOKMARK requires: aaa %ACTION% bbb'
                );
            } else {
                warnings.push(
                    <div className="warning" key="bookmark">
                        <i className="fa fa-info-circle" />
                        {parts[0]}
                        <span className="action" onClick={showBookmarkSelector}>
                            bookmark
                        </span>
                        {parts[1]}
                    </div>
                );
            }
        }

        return warnings;
    };

    renderAnnotationList = (annotationClient, resource, mediaObject) => (
        <AnnotationList
            annotationClient={annotationClient}
            resource={resource}
            mediaObject={mediaObject}
        />
    );

    renderActive() {
        // get active project
        const activeProject = this.context.activeProject;
        const isBookmarked = activeProject && this.state.isBookmarked;

        // Check if the resource has been bookmarks
        // TODO: it would be nice to have an easier way of knowing if the resource is bookmarked
        if (activeProject && !isBookmarked) {
            this.isBookmarked(this.context.user.id, activeProject);
        }

        // Warnings that can be shown before showing the annotation list
        const warnings = this.renderWarningList(
            activeProject,
            isBookmarked,
            this.props.showBookmarkSelector
        );

        // annotationsList is only created if there is an active project selected
        const annotationList =
            warnings.length == 0
                ? this.renderAnnotationList(
                      this.context.annotationClient,
                      this.context.resource,
                      this.context.activeMediaObject
                  )
                : null;

        return (
            <>
                <ColumnHeader key="columnheader" onClose={this.toggleColumn}>
                    <Tabs tabs={this.tabs} activeTab={this.state.activeTab} />
                </ColumnHeader>
                <div key="column-content" className="column-content">
                    {warnings}
                    {annotationList}
                </div>
            </>
        );
    }

    renderInactive() {
        return (
            <div onClick={this.toggleColumn}>
                <div className="icon" />
                <div className="title">{Strings.MY_ANNOTATIONS_TITLE}</div>
            </div>
        );
    }

    render() {
        return (
            <BaseColumn
                className={classNames(
                    IDUtil.cssClassName('annotation-column'),
                    {
                        active: this.props.active,
                        inactive: !this.props.active
                    }
                )}
            >
                {this.props.active
                    ? this.renderActive()
                    : this.renderInactive()}
            </BaseColumn>
        );
    }
}

AnnotationColumn.propTypes = {
    showBookmarkSelector: PropTypes.func.isRequired,
    onToggle: PropTypes.func.isRequired,
    active: PropTypes.bool.isRequired
};
