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

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

import IDUtil from '../../util/IDUtil';
import ComponentUtil from '../../util/ComponentUtil'
import TimeUtil from "../../util/TimeUtil";

import SearchAPI from "../../api/SearchAPI";

import Loading from '../../components/shared/Loading';

import { Label, CartesianGrid, XAxis, YAxis, Tooltip, ResponsiveContainer, BarChart, Legend, Bar } from 'recharts';

//TODO move same functions as in QuerySingleLineChart into something else
export default class TermHistogram extends React.Component {

	constructor(props) {
		super(props);
		this.state = {
            viewMode: 'absolute', // Sets default view mode to absolute.
            relativeData : null, //loaded for the first time after switching to 'relative'
            isLoading: false
        }
	}

    switchViewMode = () => {

        if (this.state.viewMode === 'absolute') {
            if (this.state.relativeData === null) {
                this.fetchRelativeData({
                    ...this.props.query,
                    term: '',
                    selectedFacets: {},
                    dateRange: {
                        ...this.props.query.dateRange,
                        end: null,
                        start: null
                    }
                });
            } else {
                // there is already relative Data available to draw graph.
                this.setState({viewMode: 'relative', isLoading: false})
            }
        } else {
            this.setState({viewMode: 'absolute', isLoading: false})
        }
    };

    fetchRelativeData(query) {

        this.setState({
            isLoading : true
        }, () => {
            SearchAPI.search(query, this.props.collectionConfig, this.onRelativeDataFetched, false);
        });
    }

    onRelativeDataFetched = resultsObj => { //instance of SearchResults

        if (resultsObj && resultsObj.aggregations && !resultsObj.error) {
            const totalTermCounts = resultsObj.aggregations[this.props.selectedKeywordField];
            const commonData = totalTermCounts.filter(aggr => {
                return this.props.data.find(absAggr => absAggr.key === aggr.key) != null;
            });
            this.setState({relativeData: commonData, viewMode: 'relative', isLoading: false});
        }
    };

    calcRelativePercentage = (absCount, totalCount) => {
        return absCount !== 0 && totalCount !== 0 ? ((absCount / totalCount) * 100) : 0;
    };

    filterByCurrentTerm= e => {
        // run only if there is a key and the number of results is > 0.

        if(e.key && e.count) {
            this.props.onClick(e.key);
        }
    };


    render() {
        const strokeColors = ['#468dcb', 'crimson'];
        let dataPrettyfied = null;
        if(this.props.data) {
            if(this.state.viewMode === 'absolute') {
                dataPrettyfied = this.props.data.slice(0,this.props.termLimit).map((absData, i) => {
                    const point = {};
                    point["dataType"] = 'absolute';
                    point["fill"] = strokeColors[0];
                    point["key"] = absData.key;
                    point["count"] = absData ? absData.doc_count : 0;
                    return point;
                });
            } else if(this.state.relativeData) {
                dataPrettyfied = this.props.data.slice(0,this.props.termLimit).map((absData, i) => {
                    const relData = this.state.relativeData.find(x => x.key === absData.key);
                    const point = {};
                    point["dataType"] = 'relative';
                    point["fill"] = strokeColors[0];
                    point["key"] = absData.key;
                    point["count"] = relData ? this.calcRelativePercentage(absData.doc_count, relData.doc_count) : 0; //FIXME this should never happen, but still...
                    return point;
                });
            } else {
                console.error('this should never happen')
            }
        }

        if(dataPrettyfied) {
            //const hitsOutsideRange = this.props.data.filter(aggr => !this.calcDateInRange(aggr)).reduce((acc, cur) => acc += cur.doc_count, 0);
            const loadingMsg = this.state.isLoading ? <Loading message="Loading graph..."/>: null ;
            let legendTitle = 'Histogram of ' + this.props.title + ' for query results ';
            return (
            	<div className={IDUtil.cssClassName('histogram')}>
                    {loadingMsg}
    				<span className="ms_toggle_btn" >
                        <input id="term-toggle-1" className="checkbox-toggle checkbox-toggle-round" type="checkbox" onClick={this.switchViewMode}/>
                        <label htmlFor="term-toggle-1" data-on="Relative" data-off="Absolute"/>
                    </span>
    				<ResponsiveContainer width="100%" minHeight="440px" height="40%">
    					<BarChart width={830} height={250} data={dataPrettyfied} barCategoryGap="1%" margin={{left: 10, right: 20}}>
                            <Legend verticalAlign="top" height={36}/>
    						<CartesianGrid strokeDasharray="1 6"/>
    						<XAxis dataKey="key" interval={0} height={180} tickFormatter={ComponentUtil.formatLabel} tickMargin={10} tick={{ angle: 45}} minTickGap={0} textAnchor="start">
                            	<Label value={this.props.title} offset={-20} position="bottom"
    								   style={{fontSize: 1.4 + 'rem', fontWeight:'bold'}}/>
    						</XAxis>
    						<YAxis tickFormatter={ComponentUtil.formatNumber} width={100}>
                                <Label value={this.state.viewMode === 'absolute' ? "Number of records" : "Percentage of records"}  offset={10} position="insideBottomLeft" angle={-90}
                                       style={{fontSize: 1.4 + 'rem', fontWeight:'bold', height: 460 + 'px', width: 100 + 'px' }}/>
    						</YAxis>
    						<Tooltip content={<CustomTooltip/>}/>
    						<Bar background={ {fill: 'transparent'} } onClick={this.filterByCurrentTerm}  dataKey="count" fill="#468dcb" name={legendTitle}/>
    					</BarChart>
    				</ResponsiveContainer>
    			</div>
            )
        } else {
            return (
                <div className={IDUtil.cssClassName('histogram')}>
                    Loading data...
                </div>
            )
        }
    }
}

TermHistogram.propTypes = {
    title : PropTypes.string,
    query : Query.getPropTypes(true),
    data : PropTypes.arrayOf(PropTypes.shape({ // represents a termaggregation (from ES)
        key: PropTypes.string, //e.g "nieuws"
        doc_count: PropTypes.number, //e.g. 32
    })),
    selectedKeywordField: PropTypes.string,
  collectionConfig : PropTypes.object.isRequired
}

class CustomTooltip extends React.Component {
    render() {
        const {active} = this.props;
        if (active) {
            const payload = this.props.payload;
            if(payload && payload[0]) {
                const label = payload[0].payload.key;
                const relativeValue = payload[0].value ? parseFloat(payload[0].value.toFixed(2)) : 0;
                const dataType = payload[0].payload.dataType;
                if (dataType === 'relative') {
                    return (
                        <div className="ms__custom-tooltip">
                            <h4>{dataType} value</h4>
                            <p>Term: <span className="rightAlign">{`${label}`}</span></p>
                            <p>Percentage: <span className="rightAlign">{ComponentUtil.formatNumber(relativeValue)}%</span></p>
                        </div>
                    );
                } else {
                    return (
                        <div className="ms__custom-tooltip">
                            <h4>{dataType} value</h4>
                            <p>Term: <span className="rightAlign">{`${label}`}</span> </p>
                            <p>Total: <span className="rightAlign">{ComponentUtil.formatNumber(payload[0].value)}</span></p>
                        </div>
                    );
                }
            }
        }

        return null;
    }
}

CustomTooltip.propTypes = {
    dataType: PropTypes.string,
    payload: PropTypes.array,
    label: PropTypes.string
};
