import AutoRequest from 'trc-client-core/src/components/AutoRequest';
import Col from 'trc-client-core/src/components/Col';
import DataTable from 'bd-stampy/components/DataTable';
import DayPicker from 'trc-client-core/src/components/DayPicker';
import Grid from 'trc-client-core/src/components/Grid';
import Input from 'trc-client-core/src/components/Input';
import Label from 'bd-stampy/components/Label';
import Button from 'bd-stampy/components/Button';
import LoadingActions from 'trc-client-core/src/global/LoadingActions';
import Loader from 'trc-client-core/src/components/Loader';
import moment from 'moment';
import React from 'react';
import REGISTRATION_STATUSES from 'trc-client-core/src/constants/RegistrationStatuses';
import Select from 'trc-client-core/src/components/Select';
import Time from 'trc-client-core/src/components/Time';
import {connect} from 'react-redux';
import {fromJS, Map} from 'immutable';
import {requestRegistrationDataExport} from 'trc-client-core/src/admin/AdminActions';
import {requestRegistrationData} from 'trc-client-core/src/admin/AdminDuck';

import {
    ADMIN_EXPORT_REGISTRATION_FETCH,
    ADMIN_EXPORT_REGISTRATION_ERROR
} from 'trc-client-core/src/constants/ActionTypes';

function filterServerQuery(query){
    return {
        regDateFrom: query.regDateFrom,
        regStatus: query.regStatus,
        regDateTo: query.regDateTo
    }
}


var AdminRegistrationExport = React.createClass({
    displayName: 'AdminRegistrationExport',
    contextTypes: {
        history: React.PropTypes.object
    },
    runDataExport() {
        LoadingActions.startLoading();
        requestRegistrationDataExport(filterServerQuery(this.props.location.query))
            .then(
                () => LoadingActions.showMessage('success long', 'Data Export Started'),
                () => LoadingActions.showMessage('failure long', 'Something broke unexpectedly')
            );
    },
    componentWillMount() {
        var {
            query: {
                regDateFrom,
                regDateTo
            },
            pathname
        } = this.props.location;
        if(!regDateFrom || !regDateTo) {
            this.context.history.replaceState(null, pathname, {
                ...this.props.location.query,

                // use the query params if they are provided.
                // else check if the opposite param is defined and either add or subtract a day appropriately.
                // else use today for regDateTo and yesterday for regDateFrom.
                regDateFrom: regDateFrom || (regDateTo) ? moment(regDateTo).subtract(1, 'day').format('YYYYMMDD') : moment().subtract(1, 'day').format('YYYYMMDD'),
                regDateTo: regDateTo || (regDateFrom) ? moment(regDateFrom).add(1, 'day').format('YYYYMMDD') : moment().format('YYYYMMDD')
            });
        }
    },
    getTableSchema() {

        function commentDetails(ii) {
            return fromJS(ii).getIn(['registrationDetails','commentDetailsMap']);
        }

        return [{
            heading: 'Participant',
            filter: ii => ii.registrationDetails.participantData.fullName
        }, {
            heading: 'Course',
            filter: ii => ii.registrationDetails.courseMatrix.abbreviatedName
        }, {
            heading: 'SO ID',
            filter: ii => ii.registrationDetails.soData.soId
        }, {
            heading: 'Enrollment Date',
            filter: ii => commentDetails(ii).getIn(['ENROLL', 'commentDate']),
            render: ii => <Time nullValue="-" format="MMM-DD-YY HH:mm:ss">{commentDetails(ii).getIn(['ENROLL', 'commentDate'])}</Time>
        }, {
            heading: 'Cancellation Date',
            filter: ii => commentDetails(ii).getIn(['CANCELLED', 'commentDate']),
            render: ii => <Time nullValue="-" format="MMM-DD-YY HH:mm:ss">{commentDetails(ii).getIn(['CANCELLED', 'commentDate'])}</Time>
        }, {
            heading: 'Status',
            filter: ii => fromJS(ii).getIn(['registrationDetails', 'registrationProcess']),
            render: ii => <span className={`t-${ii.process}`}>{fromJS(ii).getIn(['registrationDetails', 'registrationProcess'])}</span>
        }, {
            heading: 'Comments',
            render: ii => {
                return commentDetails(ii).map((ii, key) => {
                    var manager = ii.getIn(['commentBy', 'fullName']);
                    var message = ii.get('message');
                    if (key === 'CANCELLED') {
                        return <div>
                            <div>Cancelled by: {manager}</div>
                            <small><strong>Reason: </strong>{message}</small>
                        </div>
                    }
                    return <div>{`${message}: ${manager}`}</div>
                }).toList();
            }
        }]
    },
    onPagingate(e, page) {
        var {pathname, query} = this.props.location;
        this.context.history.pushState(null, pathname, {
            ...query,
            page: page
        });
    },
    render() {
        var {regDateFrom, regDateTo, regStatus} = this.props.location.query;

        const changeQuery = (location) => (ee, data) => {
            this.context.history.pushState(null, location.pathname, {
                ...location.query,
                [data.key]: data.value
            });
        };

        const changeDateQuery = (location) => (data) => {
            this.context.history.pushState(null, location.pathname, {
                ...location.query,
                [data.key]: data.value
            });
        };

        const options = fromJS(REGISTRATION_STATUSES)
            .unshift(Map({
                label: "ALL",
                value: ""
            }))
            .toJS();

        return (
            <div>
                <Grid>
                    <Col>
                        <h1>Export Registration Data</h1>
                    </Col>
                    <Col width="4">
                        <Label>Status</Label>
                        <Select
                            name="regStatus"
                            options={options}
                            value={regStatus}
                            onChange={changeQuery(this.props.location)}
                             />
                    </Col>
                </Grid>

                <Grid modifier="middle" className="margin-top margin-bottom3">
                    <Col>
                        <DayPicker name="regDateFrom" value={regDateFrom} format="YYYYMMDD" onChange={changeDateQuery(this.props.location)}/>
                    </Col>
                    <Col width="1">
                        <h2 className="t-center">to</h2>
                    </Col>
                    <Col>
                        <DayPicker name="regDateTo" value={regDateTo} fromMonth={moment(regDateFrom).toDate()} format="YYYYMMDD" onChange={changeDateQuery(this.props.location)}/>
                    </Col>
                </Grid>

                <Grid>
                    <Col>
                        <Button modifier="edit" className="Button Button-admin float-right" onClick={this.runDataExport}>Run Data Export</Button>
                    </Col>
                </Grid>

                {this.renderTable()}

            </div>
        );
    },
    renderTable() {
        if(this.props.fetching) {
            return <Loader/>;
        }
        var {page, search} = this.props.location.query;
        var pageAmmount = 50;
        var currentPage = parseInt(page, 10) || 0;

        return <div>
            <h2 className="hug-top">Results</h2>
            <Input name="search" queryString placeholder="Search results" className="w40"/>
            <DataTable
                modifier="data"
                schema={this.getTableSchema()}
                pagination={true}
                paginationLength={pageAmmount}
                paginationPage={currentPage}
                onPagingate={this.onPagingate}
                data={this.props.registration.filter(ii => search ? ii.toString().indexOf(search) !== -1 : true).toJS()}/>
        </div>

    }
});

const autoRequest = AutoRequest(
    [
        'location.query.regDateFrom',
        'location.query.regStatus',
        'location.query.regDateTo'
    ],
    (props) => {
        props.dispatch(requestRegistrationData(filterServerQuery(props.location.query)));
    }
);

const connectWithAdminData = connect(state => {
    return {
        registration: state.admin.get('registration'),
        fetching: state.async.get(ADMIN_EXPORT_REGISTRATION_FETCH),
        error: state.async.get(ADMIN_EXPORT_REGISTRATION_ERROR)
    }
});

export default connectWithAdminData(autoRequest(AdminRegistrationExport));
