import React, { Component } from 'react';
import PropTypes from 'prop-types'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Grid, Row, Col, Tab, TabContainer, Glyphicon, Badge, Nav, NavItem } from 'react-bootstrap';
import DatasetTable from '../../components/Dataset/DatasetTable.js';
import { PERSPECTIVE } from '../../constants/Perspectives.js';
import { addDatasetById, removeDatasetById } from '../../actions/selection.js';
import LogbookContainer from '../Logbook/LogbookContainer';
import Loader from 'react-loader-advanced';
import { setBreadCrumbs } from '../../actions/breadcrumbs.js';
import { fetchDatasetsByDOI, fetchDatasetsByInvestigationId } from '../../actions/datasets.js';
import _ from "lodash";


class InvestigationContainer extends Component {
    constructor(props) {
        super(props);
        this.state = {
            activeTab: this.props.activeTab || 1
        }
        this.handleSelect = this.handleSelect.bind(this);
    }

    onLogbookButtonClicked() {
        this.setState({
            perspective: PERSPECTIVE.EVENTS
        });
    }

    loadDatasetsByInvestigationId() {
        let { investigationId } = this.props;

        if (investigationId) {
            if (this.props.user.sessionId) {
                this.props.fetchDatasetsByInvestigationId(this.props.user.sessionId, investigationId);

                let investigation = _.find(this.props.myInvestigations, (investigation) => { return investigation.id === Number(investigationId) });

                if (investigation) {
                    // investigation was found in my Data
                    this.props.setBreadCrumbs([
                        { name: 'My Data', link: '/investigations' },
                        { name: investigation.visitId.toUpperCase(), link: '/investigations' },
                        { badge: investigation.name, name: investigation.summary, link: '/investigation/' + investigation.id + '/datasets' }
                    ]);
                } else {
                    // investion not found in my data, it can be among closed data
                    investigation = _.find(this.props.investigations, (investigation) => { return investigation.id === Number(investigationId) });

                    if (investigation) {
                        // investigation was found in my Data
                        this.props.setBreadCrumbs([
                            { name: 'Closed Data', link: '/closed' },
                            { name: investigation.visitId.toUpperCase(), link: '/investigations' },
                            { name: investigation.name + ": " + investigation.summary, link: '/investigation/' + investigation.id + '/datasets' }
                        ]);
                    }

                }

            }
        }
    }

    setDOIBreadCrumbs(doi) {
        this.props.setBreadCrumbs([{ name: 'Open Data', link: '/public' }, { badge: doi, name: '', link: '/public/' + doi }]);
    }

    componentWillReceiveProps(nextProps) {
        /** If component was mounted when sessionId was still not ready */
        if (!this.props.user.sessionId) {
            if (nextProps.user.sessionId) {
                if (nextProps.user.sessionId !== this.props.user.sessionId) {
                    this.fetchData(nextProps.user.sessionId);
                    this.setDOIBreadCrumbs(this.props.doi);
                }
            }
        }

        if (this.props.doi) {
            this.setDOIBreadCrumbs(this.props.doi);
        }
    }

    fetchData(sessionId) {
        if (this.props.doi != null) {
            if (sessionId) {
                this.props.fetchDatasetsByDOI(sessionId, this.props.doi);
            }
        }
        else {
            this.loadDatasetsByInvestigationId();
        }
    }
    /**
     * If this props.doi this method will load the datasets that belongs to a doi
     * otherwise it will load the datasets of a investigation
     */
    componentDidMount() {
        this.fetchData(this.props.user.sessionId);
    }

    /**
     * Function triggered when the user click to view another tab
     * @param key {integer} a number corresponding to the tab which is being clicked. 1=datasets, 2=files, 3=events
     */
    handleSelect(key) {
        this.setState({ activeTab: key });
        // The code below changes the content of the address bar. It does not reload the page.
        let pathname = this.props.history.location.pathname;
        let lastSlashPosition = pathname.lastIndexOf('/');
        let addressBar = pathname.slice(0, lastSlashPosition)
        if (key === 1) {
            addressBar = addressBar + '/datasets'
        } else if (key === 2) {
            addressBar = addressBar + '/files'
        } else if (key === 3) {
            addressBar = addressBar + '/events'
        }
        this.props.history.push(addressBar);
    }

    render() {
        /** Array with ID for the rows that will be expanded by default        */
        let expanded = [];

        /** Search proposal */
        var _this = this;
        var investigation = _.find(this.props.releasedInvestigations.concat(this.props.myInvestigations).concat(this.props.investigations), function (i) { return i.id === _this.props.investigationId; });
        if (investigation) {
            if (investigation.visitId === "publisher") {
                expanded = _.map(this.props.datasets.data, function (d) { return d.id; });
            }
        }
        /** If no user or sessionId return nothing */
        if ((!this.props.user) || (!this.props.user.sessionId)) {
            return null;
        }

        return (<Grid fluid>
            <TabContainer id="tabs" activeKey={this.state.activeTab} onSelect={this.handleSelect}>
                <Row >
                    <Col sm={12}>
                        <TabContainerMenu isLogBookTabDisplayed={!this.props.isDOI} datasetCount={this.props.datasets.data.length} />
                        <Tab.Content animation>
                            <Tab.Pane eventKey={1} mountOnEnter={true}>
                                <Loader show={this.props.datasets.fetching}>
                                    <DatasetTable
                                        selection={this.props.selection}
                                        removeDatasetById={this.props.removeDatasetById}
                                        addDatasetById={this.props.addDatasetById}
                                        sessionId={this.props.user.sessionId}
                                        expanded={expanded}
                                        datasets={this.props.datasets.data}
                                        fetching={this.props.datasets.fetching}>
                                    </DatasetTable>
                                </Loader>
                            </Tab.Pane>
                            <Tab.Pane eventKey={3} mountOnEnter={true}>
                                <LogbookContainer investigationId={this.props.investigationId} />
                            </Tab.Pane>
                        </Tab.Content>
                    </Col>
                </Row>
            </TabContainer>
        </Grid>)
    }
}

function TabContainerMenu(props) {
    var logbookClassName = "";
    if (!props.isLogBookTabDisplayed) {
        logbookClassName = "hidden";
    }
    return (
        <Nav bsStyle="tabs">
            <NavItem eventKey={1}>
                <div>
                    <Glyphicon glyph="list" />
                    <span style={{ marginLeft: "2px" }}> Dataset List &nbsp;</span>
                    <Badge bsClass="ourBadges-m"> {props.datasetCount} </Badge>
                </div>
            </NavItem>

            <NavItem className={logbookClassName} eventKey={3} >
                <div>
                    <Glyphicon glyph="comment" />
                    <span style={{ marginLeft: "2px" }}> Logbook </span>
                </div>
            </NavItem>
        </Nav>
    )
}

function mapStateToProps(state) {
    return {
        datasets: state.datasets,
        events: state.events,
        investigations: state.investigations.data,
        myInvestigations: state.myInvestigations.data,
        releasedInvestigations: state.releasedInvestigations.data,
        selection: state.selection,
        user: state.user
    };
}


function mapDispatchToProps(dispatch) {
    return {
        removeDatasetById: bindActionCreators(removeDatasetById, dispatch),
        addDatasetById: bindActionCreators(addDatasetById, dispatch),
        setBreadCrumbs: bindActionCreators(setBreadCrumbs, dispatch),
        fetchDatasetsByDOI: bindActionCreators(fetchDatasetsByDOI, dispatch),
        fetchDatasetsByInvestigationId: bindActionCreators(fetchDatasetsByInvestigationId, dispatch)
    };
}


export default connect(
    mapStateToProps,
    mapDispatchToProps
)(InvestigationContainer);


InvestigationContainer.propTypes = {
    perspective: PropTypes.oneOf([PERSPECTIVE.DATASETS, PERSPECTIVE.FILES, PERSPECTIVE.EVENTS]),
    /** 
     * the tab which will be displayed 1=dataset tab, 2=file tab, 3=events tab
     */
    activeTab: PropTypes.number
}
