import React, { Component } from 'react';
import PropTypes from 'prop-types';

import { connect } from 'react-redux';
import { fetchPayments, fetchCategories, paymentReportAction, selector, paymentSummaryReport, paymentStatusReportAction, paymentTimelineReportAction } from './redux.js';

//components
import PaymentItems from 'components/PaymentItems';
import PaymentList from 'components/PaymentList';
import FetchedContent from 'components/FetchedContent';
import { ActivityIndicator, Button, ButtonBar, PageSwitcher, ListMessagePanel, ListTitle, SectionHeader, ToolbarButton, Toolbar, ToolbarSection, ToolbarButtons, ToolbarRow } from 'lib/components';
import { PeriodTitle, getPeriodParams } from 'containers/Params';

import { Doughnut } from 'react-chartjs-2';
import DoughnutChartLegend from 'components/DoughnutChartLegend';

import StatusChart from 'components/StatusChart';
import PaymentTimelineChart from 'components/PaymentTimelineChart';

import { injectIntl } from 'react-intl';
import icons from 'constants/icons';
import palette from 'utils/palette';
import { formatDate, formatMoney, formatNumber } from 'lib/i18n'
import { settingsSelector } from 'utils/settings';

import messages from './messages.js';


class DashboardStatusChart extends Component {

    render() {
        let { data, status, i18n, intl, unit } = this.props;

        return (
            <div className="relative">
                { data ? (
                    <div className="hover-highlight-light">
                        <StatusChart 
                            data={ data.data } 
                            currency={ data.currencySymbol || data.currency || unit.currencySymbol || unit.currency } 
                            i18n={ i18n } 
                            /> 
                    </div> 
                ): null }
                <ActivityIndicator show={ status === "pending" } type="overlay" size="big" />
            </div>
        );  
    }
}

DashboardStatusChart = connect(settingsSelector((state, props) => state.getIn(["paymentList", "statusReport"]).toJS()), () => ({}) )(DashboardStatusChart);
DashboardStatusChart = injectIntl(DashboardStatusChart);


class Payments extends Component {


    constructor(props) {
        super(props);

        this.renderSummary = this.renderSummary.bind(this);
        this.renderPayments = this.renderPayments.bind(this);
        this.renderCategories = this.renderCategories.bind(this);

        this.changePeriod = this.changePeriod.bind(this);
    }


    componentWillMount() {
        let { payments } = this.props;
        /*
        this.props.fetchPayments(this.props.unitId, payments.filetr, payments.paging, payments.sorting);
        */
        this.props.fetchCategories(this.props.unitId);
        this.changePeriod(this.props.periodParams, this.props.payments.paging, this.props.payments.sorting);
    }


    changePeriod(periodParams, paging, sorting) {
        let unitId = this.props.unitId;
        let { from, to } = periodParams;

        this.props.fetchPayments(unitId, { from, to }, paging, sorting);
        this.props.paymentReportAction(unitId, { from, to });
        this.props.paymentTimelineReportAction(unitId, { from, to });
        this.props.paymentStatusReportAction(unitId, { from, to });
    }


    renderSummary(intl, summary = {}, i18n, unit, status) {
        if (!summary) {
            return null;
        }

        let { data: reportData } = summary;

        let sums = [];
        let vals = [];
        let labels = [];
        let total = 0;
        let percents = [];
        let s = null;
        let colors = [];
        let currency = null;

        if (Array.isArray(reportData)) {
            colors = palette(global._chartColors, reportData.length)
            for (let i = 0; i < reportData.length; i++) {
                s = reportData[i];
                labels.push(s.name);
                sums.push(s.total);
                vals.push(s.total);
                total += s.total;
                if (!currency) {
                    currency = s.currencySymbol || s.currency;
                }
            }
        }

        if (total == 0) {
            sums = sums.map(s => 1);
            percents = vals;
        } else {
            percents = sums.map(s => s / total * 100);
        }

        let data = {
            labels: labels,
            datasets: [{
                data: sums,
                backgroundColor: colors
            }]
        };

        let options = {
            cutoutPercentage: 65,
            animate: false,
            maintainAspectRatio: false,
            legend: {
                animate: false,
                display: false 
            },
            animation: {
                animateScale: false,
                animateRotate: false,
            },    
            tooltips: {
                callbacks: {
                    label: function(tti, data) {
                        if (total == 0) {
                            return formatMoney(0, currency);    
                        }
                        return formatMoney(data.datasets[0].data[tti.index], currency);
                    }               
                }
            },

        };

        return (
            <div className="status-chart mv20 relative">
                <div>
                    <div className="status-chart-div">
                        <Doughnut data={ data } options={ options } redraw={ true } />
                    </div>
                </div>
                <div>
                    <DoughnutChartLegend labels={ labels } colors={ colors } values={ vals } percents={ percents } currency={ currency } i18n={ i18n } />
                </div>
                <ActivityIndicator show={ status === "pending" } type="overlay" size="big" />                
            </div>
        );
    }


    renderPayments(intl, payments = {}) {
        let { list = {} } = payments;
        let pending = list.status == "pending";

        return (
            <div>
                <FetchedContent 
                    status={ list && list.status } 
                    error={ list && list.error } 
                    fresh={ list && list.fresh } 
                    empty={ !payments || !list.data || !list.data.length } 
                    buttons={ [
                        <ToolbarButton 
                            key="rec"
                            label={ intl.formatMessage(messages.addRECPayment) }
                            onClick={ () => this.context.router.push("/payments/rec/new") } 
                            >
                            <span className="icon">{ icons.add }</span>
                        </ToolbarButton>,
                        <ToolbarButton 
                            key="ot"
                            label={ intl.formatMessage(messages.addOTPayment) }
                            onClick={ () => this.context.router.push("/payments/ot/new") } 
                            >
                            <span className="icon">{ icons.add }</span>
                        </ToolbarButton>

                    ] }
                    >

                    <PaymentItems 
                        items={ list.data } 
                        onDetailClick={ (id) => this.context.router.push(`/payments/${id}`)} 
                        i18n={ this.props.i18n }
                        disabled={ pending }
                        />
                    { list.data ? 
                        <PageSwitcher
                            paging={ list.paging } 
                            onPageChanged={ (paging) => this.props.fetchPayments(this.props.unitId, list.filter, paging, list.sorting) } 
                            status={ list.status } 
                            disabled={ pending }
                            /> : null 
                    }
                </FetchedContent>

            </div>
        );
    }


    renderCategories(intl, categories = {}, report) {
        let content = null;
        let { list } = categories;
        let pending = list.status == "pending";

        let stats = {};
        if (report && report.data && Array.isArray(report.data.data)) {
            for (let i = 0; i < report.data.data.length; i++) {
                stats[report.data.data[i].id] = report.data.data[i];
            }
        }

        return (
            <div>
                <FetchedContent 
                    status={ (list && list.status == "pending") || (report && report.status == "pending") ? "pending" : "success" } 
                    error={ list && list.error } 
                    fresh={ list && list.fresh } 
                    empty={ !list || !list.data || !list.data.length } 
                    buttons={ 
                        <ToolbarButton 
                            label={ intl.formatMessage(messages.addCategory) }
                            onClick={ () => this.context.router.push(`/payments/categories/new`) } 
                            >
                            <span className="icon">{ icons.add }</span>
                        </ToolbarButton>
                    }
                    >

                    <div className="">
                        <PaymentList 
                            items={ list.data } 
                            pending={ pending }
                            stats={ stats }
                            onDetailClick={ (id) => this.context.router.push(`/payments/categories/${id}`)}
                            i18n={ this.props.i18n }
                            disabled={ pending }
                            />
                        { list.data ? 
                            <PageSwitcher 
                                paging={ list.paging } 
                                onPageChanged={ (paging) => this.props.fetchCategories(this.props.unitId, list.filter, paging, list.sorting) } 
                                status={ list.status } 
                                disabled={ pending }
                                /> : null 
                        }
                    </div>

                </FetchedContent>
            </div>
        );
    }


    render() {
        let { intl, pending, payments, categories, report, periodParams={}, i18n, unit } = this.props;

        return (
            <div className="pv10">
                <Toolbar>
                    <ToolbarSection>
                        <ListTitle 
                            title={ intl.formatMessage(messages.title) }
                            titleIcon={ icons.payments }
                            />
                    </ToolbarSection>
                    <ToolbarButtons>
                        <ToolbarButton 
                            label={ intl.formatMessage(messages.addCategory) }
                            onClick={ () => this.context.router.push(`/payments/categories/new`) } 
                            >
                            <span className="icon">{ icons.add }</span>
                        </ToolbarButton>
                        <ToolbarButton 
                            label={ intl.formatMessage(messages.addRECPayment) }
                            onClick={ () => this.context.router.push("/payments/rec/new") } 
                            >
                            <span className="icon">{ icons.add }</span>
                        </ToolbarButton>
                        <ToolbarButton 
                            label={ intl.formatMessage(messages.addOTPayment) }
                            onClick={ () => this.context.router.push("/payments/ot/new") } 
                            >
                            <span className="icon">{ icons.add }</span>
                        </ToolbarButton>
                    </ToolbarButtons>
                    <ToolbarRow>
                        <PeriodTitle
                            size="normal"
                            changePeriod={ this.changePeriod }
                            />
                    </ToolbarRow>
                </Toolbar>

                <div className="row row-margin-10">
                    <div className="col-md-6 p10">
                        <div className="hover-highlight-light p10 relative">
                            <h2>{ intl.formatMessage(messages.titleCategories) }</h2>
                            { this.renderSummary(intl, (report && report.data) || {}, i18n, unit, report && report.status) }
                        </div>
                        <div className="p10 mb30 relative">
                            { this.renderCategories(intl, categories, report) }
                        </div>
                        <div className="p10 hover-highlight-light  relative">
                            <h2 className="mb20">{ intl.formatMessage(messages.titleTimeline) }</h2>
                            { payments.timelineReport ? <PaymentTimelineChart { ...payments.timelineReport.data } /> : null }
                            <ActivityIndicator show={ payments.timelineReport && payments.timelineReport.status == "pending" } type="overlay"/> 
                        </div>
                    </div>
                    <div className="col-md-6 p10">
                        <div className="hover-highlight-light p10  relative">
                            <h2 className="mb20">{ intl.formatMessage(messages.titleStatus) }</h2>
                            <DashboardStatusChart />
                        </div>
                        <div className="relative">
                            { this.renderPayments(intl, payments) }
                        </div>
                    </div>
                </div>

            </div>
        );
    }

}

Payments.contextTypes = {
    router: PropTypes.object.isRequired
};



const mapStateToProps = selector;


function mapDispatchToProps(dispatch, props) {
    return {
        dispatch,
        fetchCategories: (unitId, filter, paging, sorting) => dispatch(fetchCategories(filter, paging, sorting, { unitId })),
        fetchPayments: (unitId, filter, paging, sorting) => dispatch(fetchPayments(filter, paging, sorting, { unitId })),
        paymentReportAction: (unitId, params) => dispatch(paymentReportAction(unitId, params)),
        paymentTimelineReportAction: (unitId, params) => dispatch(paymentTimelineReportAction(unitId, params)),
        paymentStatusReportAction: (unitId, params) => dispatch(paymentStatusReportAction(unitId, params)),
        paymentSummaryReport: (unitId, params) => dispatch(paymentSummaryReport(unitId, params)),
    };
}


export default injectIntl(connect(selector, mapDispatchToProps)(Payments));
