import React, { PureComponent } from 'react';
import { Modal } from 'react-bootstrap';
import mousetrap from 'mousetrap';
import $ from 'jquery';
import { restRequest, getApiRoot } from 'girder/rest';

import './style.styl';

class MainView extends PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            postIds: [],
            postId: this.props.match.params.postId ? this.props.match.params.postId : null,
            post: null,
            showRawModal: false
        };
    }

    componentDidMount() {
        restRequest({
            url: '/post/postids'
        }).then((postIds) => {
            this.setState({ postIds });
            if (postIds.length) {
                this.loadPost(this.state.postId && postIds.indexOf(this.state.postId) !== -1 ? this.state.postId : postIds[0]);
            }
        });

        mousetrap.bind('left', () => { this.previous() });
        mousetrap.bind('right', () => { this.next() });
        mousetrap.bind('up', () => { this.setResult(true) });
        mousetrap.bind('down', () => { this.setResult(false) });
    }

    componentWillReceiveProps(nextProps) {
        if (this.props.match.params.postId !== nextProps.match.params.postId) {
            var postId = nextProps.match.params.postId;
            if (nextProps.history.action === 'POP' &&
                this.state.postId !== postId &&
                this.state.postIds.indexOf(postId) !== -1) {
                this.loadPost(postId);
            }
        }
    }

    componentWillUnmount() {
        mousetrap.unbind('left');
        mousetrap.unbind('right');
        mousetrap.unbind('up');
        mousetrap.unbind('down');
    }

    loadPost(id) {
        this.setState({
            postId: id,
        }, () => {
            restRequest({
                url: `/post/${id}`
            }).then((post) => {
                this.setState({
                    post
                });
            });
        });
        var url = '/post/' + id;
        if (this.props.match.url !== url) {
            if (this.props.match.params.postId) {
                this.props.history.push(url);
            } else {
                this.props.history.replace(url);
            }
        }
    }

    existNext() {
        var currentIndex = this.state.postIds.indexOf(this.state.postId);
        return currentIndex < this.state.postIds.length - 1;
    }

    next() {
        var currentIndex = this.state.postIds.indexOf(this.state.postId);
        if (this.existNext()) {
            this.loadPost(this.state.postIds[currentIndex + 1]);
        }
    }

    existPrevious() {
        var currentIndex = this.state.postIds.indexOf(this.state.postId);
        return currentIndex - 1 >= 0;
    }

    previous() {
        var currentIndex = this.state.postIds.indexOf(this.state.postId);
        if (this.existPrevious()) {
            this.loadPost(this.state.postIds[currentIndex - 1]);
        }
    }

    setResult(result) {
        var result = { result: this.state.post.result === result ? null : result };
        restRequest({
            method: 'PUT',
            contentType: 'application/json',
            url: `/post/${this.state.postId}/result`,
            data: JSON.stringify(result)
        }).then(() => {
            this.setState({ post: { ...this.state.post, ...result } });
        })
    }

    setImageResult(imageResult) {
        var imageResult = { imageResult: this.state.post.imageResult === imageResult ? null : imageResult };
        restRequest({
            method: 'PUT',
            contentType: 'application/json',
            url: `/post/${this.state.postId}/imageresult`,
            data: JSON.stringify(imageResult)
        }).then(() => {
            this.setState({ post: { ...this.state.post, ...imageResult } });
        })
    }

    render() {
        if (!this.state.post) {
            return <div className='no-data'>No data found. Navigate to <a target='_blank' href='/api/v1#!/post/post_importData'>here</a> to import data, and <a target='_blank' href='/api/v1#!/post/post_setImagePath'>here</a> to and set image path</div>
        }
        var original = this.state.post.original;
        return <div className={['main-view', this.props.className].join(' ')}>
            <div className='container-fluid'>
                <div className='row control'>
                    <div className='col-xs-4'>
                        <input className='page-number' type='number' value={this.state.postIds.indexOf(this.state.postId) + 1} onChange={(e) => {
                            var index = parseInt(e.target.value) - 1;
                            if (!index || index < 0 || index > this.state.postIds.length - 1) {
                                return;
                            }
                            var postId = this.state.postIds[index];
                            this.setState({ postId });
                            this.loadPost(postId);
                        }} />
                        <span> / {this.state.postIds.length}</span>
                    </div>
                    <div className='col-xs-4 buttons'>
                        <div className='row'>
                            <div className='col-xs-9'>
                                <div className='btn-group'>
                                    <button className='previous-frame btn btn-default'
                                        disabled={!this.existPrevious()}
                                        onClick={() => this.previous()}>
                                        <i className='icon-to-start'></i>
                                    </button>
                                    <button className='next-frame btn btn-default'
                                        disabled={!this.existNext()}
                                        onClick={() => this.next()}>
                                        <i className='icon-to-end'></i>
                                    </button>
                                </div>
                                <div className='btn-group'>
                                    <button className={`play btn ${this.state.post.result === true ? 'btn-success' : 'btn-default'}`}
                                        onClick={() => this.setResult(true)}>
                                        <span className='glyphicon glyphicon-thumbs-up'></span>
                                    </button>
                                    <button className={`play btn ${this.state.post.result === false ? 'btn-danger' : 'btn-default'}`}
                                        onClick={() => this.setResult(false)}>
                                        <span className='glyphicon glyphicon-thumbs-down'></span>
                                    </button>
                                </div>
                            </div>
                            <div className='col-xs-3'>
                                <span>{this.state.post.resultUser}</span>
                            </div>
                        </div>
                    </div>
                    <div className='col-xs-4'>
                        <a onClick={(e) => this.setState({ showRawModal: true })}>{this.state.postId}</a>
                    </div>
                </div>
                <div className="row image-label">
                    <div className="col-xs-7"></div>
                    <div className="col-xs-5">
                        <div className='btn-group'>
                            <button className={`play btn ${this.state.post.imageResult === true ? 'btn-success' : 'btn-default'}`}
                                onClick={() => this.setImageResult(true)}>
                                <span className='glyphicon glyphicon-thumbs-up'></span>
                            </button>
                            <button className={`play btn ${this.state.post.imageResult === false ? 'btn-danger' : 'btn-default'}`}
                                onClick={() => this.setImageResult(false)}>
                                <span className='glyphicon glyphicon-thumbs-down'></span>
                            </button>
                        </div>
                        <span className="image-result-label">(Image Label)</span>
                    </div>
                </div>
                <div className='row post'>
                    <div className='col-xs-3 tags'>
                        <ul>
                            {original.tags && original.tags.map((tag, i) => <li key={i}>{tag}</li>)}
                        </ul>
                    </div>
                    <div className='col-xs-4'>
                        {original.caption && original.caption.text}
                    </div>
                    <div className='col-xs-5 image-container'>
                        <img key={original.id} src={`${getApiRoot()}/post/${getImageName(original.id)}/image`} onLoad={(e) => {
                            var $img = $(e.target);
                            var imageRatio = $img.height() / $img.width();
                            var $imageContainer = $img.parent();
                            var parentRatio = $imageContainer.height() / $imageContainer.width();
                            if (imageRatio > parentRatio) {
                                $img.css({ height: '100%', width: 'auto' });
                            }
                            else {
                                $img.css({ width: '100%', height: 'auto' });
                            }
                        }} />
                    </div>
                </div>
            </div>
            <Modal show={this.state.showRawModal} onHide={() => { this.setState({ showRawModal: false }) }} bsSize="large" >
                <Modal.Header closeButton>
                    <Modal.Title>Raw data</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <pre>{JSON.stringify(this.state.post, null, 2)}</pre>
                </Modal.Body>
            </Modal>
        </div>;
    }
}

function getImageName(url) {
    var splits = url.split('/');
    return splits[splits.length - 1];
}

export default MainView;
