import React from 'react';
import PropTypes from 'prop-types';
import { Button, Glyphicon } from 'react-bootstrap';
import './DatasetTable.css';
import axios from "axios";
import Moment from 'react-moment';
import TECHNIQUES from '../../config/techniques/techniques.js';
import Loading from '../../components/Loading.js';
import { getDatasetStatus } from "../../api/icat/icatPlus.js"
import { stringifyBytesSize } from "../Helpers.js"
import { VOLUME, FILE_COUNT } from '../../constants/ParameterTypes.js';
import ResponsiveTable from "../Table/ResponsiveTable.js";
import DatasetWidget from "./DatasetWidget.js";
import { getDatasetParameterByName } from '../../helpers/DatasetHelper.js';
import _ from 'lodash';
import {getDownloadURLByDatasetId} from "../../api/icat/icatPlus"

class DatasetTable extends React.Component {
    constructor(props) {
        super(props);
        this.techniques = TECHNIQUES;
    }


    dateFormatter(cell, row) {
        if (cell != null) {
            return <DateWidget date={cell}></DateWidget>;
        }
    }

    /**
    * This looks into the parameters of the dataset
    */
    getParameter(dataset, parameterName) {
        var parameter = _.find(dataset.parameters, function (o) { return o.name === parameterName });
        if (parameter) {
            if (parameter.value) {
                return parameter.value;
            }
        }
    }


    fileCountFormatter(cell, dataset, rowIndex, extraData) {
        return getDatasetParameterByName(dataset, FILE_COUNT);
    }

    volumeFormatter(cell, dataset, rowIndex, extraData) {
        return stringifyBytesSize(getDatasetParameterByName(dataset, VOLUME));
    }

    downloadFormatter(cell, dataset, rowIndex, extraData) {
        let dataArchived = extraData.getParameter(dataset, "__dataArchived");
        if (dataArchived === "False") {
            return "N/A";
        }
        return <DownloadButton sessionId={extraData.props.sessionId} id={dataset.id} ></DownloadButton>;
    }

    techniquesFormatter(cell, row) {
        if (row != null) {
            var definition = row.parameters.filter(function (o) { return o.name === "definition" });
            if (definition) {
                if (definition.length > 0) {
                    return definition[0].value;
                }
            }
        }
    }

    getColumns() {
        return [
            {
                text: "id",
                dataField: "id",
                hidden: true
            },
            {
                text: "Date",
                dataField: "startDate",
                sort: true,
                hidden: false,
                formatter: this.dateFormatter,
                formatExtraData: this,
                headerStyle: (column, colIndex) => {
                    return { width: "50%", textAlign: "center" };
                },
                responsiveHeaderStyle: {
                    xs: { hidden: true },
                    sm: { hidden: true },
                    md: { width: "150px" },
                    lg: { width: "150px" }
                }
            },
            {
                text: "Sample",
                dataField: "sampleName",
                sort: true,
                hidden: false,
                headerStyle: (column, colIndex) => {
                    return { width: "50%", textAlign: "center" };
                },
                responsiveHeaderStyle: {
                    xs: { hidden: true },
                    sm: { hidden: true },
                    md: { hidden: false },
                    lg: { hidden: false },
                }
            },
            {
                text: "Dataset",
                dataField: "name",
                sort: true,
                hidden: false,
                headerStyle: (column, colIndex) => {
                    return { width: "50%", textAlign: "center" };
                },
                responsiveHeaderStyle: {
                    xs: { hidden: false },
                    sm: { hidden: false },
                    md: { hidden: false },
                    lg: { hidden: false },
                }
            },
            {
                text: "Definition",
                dataField: "definition",
                formatter: this.techniquesFormatter,
                sort: true,
                hidden: false,
                headerStyle: (column, colIndex) => {
                    return { width: "50%", textAlign: "center" };
                },
                responsiveHeaderStyle: {
                    xs: { hidden: true },
                    sm: { hidden: true },
                    md: { width: "130px" },
                    lg: { width: "130px" }
                }
            },
            {
                text: "Location",
                dataField: "location",
                responsiveHeaderStyle: {
                    xs: { hidden: true },
                    sm: { hidden: true },
                    md: { hidden: true },
                    lg: { hidden: true }
                }
            },
            {
                text: "Files",
                dataField: "__fileCount",
                sort: true,
                hidden: false,
                formatter: this.fileCountFormatter,
                formatExtraData: this,
                headerStyle: (column, colIndex) => {
                    return { width: "50%", textAlign: "center" };
                },
                responsiveHeaderStyle: {
                    xs: { hidden: true },
                    sm: { hidden: true },
                    md: { width: "80px" },
                    lg: { width: "80px" }
                }
            },
            {
                text: "Size",
                dataField: VOLUME,
                sort: true,
                hidden: false,
                formatter: this.volumeFormatter,
                formatExtraData: this,
                headerStyle: (column, colIndex) => {
                    return { width: "50%", textAlign: "center" };
                },
                responsiveHeaderStyle: {
                    xs: { hidden: true },
                    sm: { hidden: true },
                    md: { width: "80px" },
                    lg: { width: "80px" }
                }
            },

            {
                text: "Download",
                dataField: "download",
                sort: true,
                hidden: false,
                formatter: this.downloadFormatter,
                formatExtraData: this,
                headerStyle: (column, colIndex) => {
                    return { width: "50%", textAlign: "center" };
                },
                responsiveHeaderStyle: {
                    xs: { hidden: true },
                    sm: { hidden: true },
                    md: { width: "110px" },
                    lg: { width: "110px" }
                }
            }
        ];
    }

    handleOnSelect = (row, isSelect) => {
        if (isSelect) {
            this.props.addDatasetById(row.id);
        }
        else {
            this.props.removeDatasetById(row.id);
        }
        return true;
    }

    handleOnSelectAll = (isSelect, rows) => {
        if (isSelect) {
            return rows.filter(r => r.id >= 3).map(r => r.id);
        }
    }


    render() {

        if (this.props.fetching) {
            return <Loading message="Loading datasets"></Loading>;
        }

        const selectRow = {
            mode: 'checkbox',
            clickToSelect: false,
            selected: this.props.selection.datasetIds,
            onSelectAll: this.handleOnSelectAll,
            onSelect: this.handleOnSelect,
            classes: 'selection-row'
        };

        const expandRow = {
            showExpandColumn: true,
            //expandByColumnOnly: true,
            expanded: this.props.expanded,
            expandColumnPosition: 'right',
            expandHeaderColumnRenderer: ({ isAnyExpands }) => {
                if (isAnyExpands) {
                    return <span style={{ fontSize: '18px' }}><Glyphicon glyph="zoom-out" /></span>;
                }
                return <span style={{ fontSize: '18px' }}><Glyphicon glyph="zoom-in" /></span>;
            },
            expandColumnRenderer: ({ expanded }) => {
                if (expanded) {
                    return (
                        <Glyphicon glyph="zoom-out" />
                    );
                }
                return (
                    <Glyphicon glyph="zoom-in" />
                );
            },
            renderer: dataset => {
                return (
                    <DatasetWidget
                        dataset={dataset}
                        sessionId={this.props.sessionId}
                        selection={this.props.selection} ></DatasetWidget>
                );
            }
        };

        return <div style={{ 'margin': '20px' }}>
            <ResponsiveTable
                keyField="id"
                data={this.props.datasets}
                columns={this.getColumns()}
                expandRow={expandRow}
                selectRow={selectRow}
            />
        </div>
    }
}

DatasetTable.propTypes = {
    datasets: PropTypes.array
};

export default DatasetTable;


class DateWidget extends React.Component {

    render() {
        return <div style={{ 'margin': '2px', height: '20px', fontSize: '11px' }}>
            <Glyphicon glyph='glyphicon glyphicon-time'></Glyphicon>
            <span style={{ 'marginLeft': '12px' }}>
                <Moment parse="YYYY-MM-DD HH:mm" format="HH:mm">{this.props.date}</Moment>
            </span>
            <br />
            <span style={{ 'marginLeft': '12px', color: 'gray' }}>
                <Moment parse="YYYY-MM-DD HH:mm" format="ll">{this.props.date}</Moment>
            </span>
        </div>;

    }
};


class DownloadButton extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            status: "FETCHING",
            fetching: false,
            fetched: false
        }
    }

    getStatus() {
        axios.get(getDatasetStatus(this.props.sessionId, this.props.id))
            .then(response => {
                this.setState({
                    status: response.data,
                    fetching: false,
                    fetched: true
                });

            })
            .catch((error) => {
                this.setState({
                    status: error.response.data.message + " " + this.props.id,
                    fetching: false,
                    fetched: true
                });
            });
    }

    restore(e) {

        axios.get(getDownloadURLByDatasetId(this.props.sessionId, this.props.id))
            .then(response => {
                this.getStatus();
            })
            .catch((error) => {
                this.getStatus();
            });

    }

    componentDidMount() {
        if (!this.state.fetching) {
            this.setState({
                fetching: true
            });
        }

        this.getStatus();

    }

    render() {
        var downloadURL = getDownloadURLByDatasetId(this.props.sessionId, this.props.id);
        if (this.state.status === 'ONLINE') {
            return <a style={{ color: 'black' }} href={downloadURL}>
                <Button bsStyle="primary" bsSize="xsmall">
                    <span className="glyphicon glyphicon-download-alt"></span>
                    <span style={{ marginLeft: '10px' }} ></span>
                    Download</Button>
            </a>;
        }

        if (this.state.status === 'RESTORING') {
            return <a style={{ color: 'black' }} href={downloadURL}>
                <Button variant="dark" bsSize="xsmall" >
                    <span bsSize="xsmall" className="glyphicon glyphicon-repeat fast-right-spinner"></span>
                    <span style={{ color: 'black', marginLeft: '10px' }} >Restoring</span>
                </Button>
            </a>;
        }

        if (this.state.status === 'ARCHIVED') {
            return <Button variant="light" bsSize="xsmall" onClick={(e) => { this.restore(e) }}>
                <span style={{ color: 'black' }} className="glyphicon glyphicon-tasks"></span>
                <span style={{ color: 'black', marginLeft: '10px' }} >Restore</span>
            </Button>;
        }

        if (this.state.status === 'FETCHING') {
            return <span><span style={{ marginLeft: '10px' }} className="glyphicon glyphicon-repeat fast-right-spinner"></span></span>;
        }

        return <span>{this.state.status}</span>;
    }

};

