import React from 'react';
import { ModelListener } from 'front';
import ManifestModel from './manifest.js';
import ManifestItemModel from './manifest-item.js';
import ManifestItem from './manifest-item.jsx';
import TextInput from '../../atoms/text-input/text-input.jsx';
import { uuidgen } from '../../etc/util';
import { moneyFormatter } from '../../etc/format';
import '../../less/grid';
import './manifest.less';

/**\

    title: Manifest
    category: component
    description:
        A collection of order manifest items
    props:
        hidePrice[Boolean]:
            toggles the visiblity of the price caluculations
            on the order manifest

\**/
class Manifest extends ModelListener {
    static defaultProps = {
        model: ManifestModel,
        hidePrice: false
    };

    constructor(props) {
        super(props);

        this.addItem = new ManifestItemModel();
        this.formatter = moneyFormatter('en-US');
    }

    assignKeys() {
        this.model.items.forEach((item) => {
            if (!item._key) {
                item._key = uuidgen();
            }
        });
    }

    add(field) {
        this.model.items.push(this.addItem.out());

        /* istanbul ignore else: no one cares */
        if (this.model.errors) {
            this.model.errors = null;
        }

        this.addItem.clear();
        this.focusOn = field;
    }

    recalc() {
        /* istanbul ignore next: enzyme doesnt handle this well */
        this.forceUpdate();
    }

    remove(idx) {
        this.model.items.splice(idx, 1);
    }

    getHeader() {
        if (this.props.hidePrice) {
            return (
                <div className="row t50-50 header">
                    <div>Item</div>
                    <div className="number">Qty</div>
                </div>
            );
        }

        return (
            <div className="row t50-16-16-16 header">
                <div>Item</div>
                <div className="number">Qty</div>
                <div className="number">Price</div>
                <div className="number">Total</div>
            </div>
        );
    }

    getSubtotal() {
        if (this.props.hidePrice) {
            return;
        }

        if (!this.model.subtotal()) {
            return;
        }

        return (
            <div className="summary">
                <div className="row t50-50">
                    <div className="title">Subtotal</div>
                    <div className="amount money">
                        { this.formatter(this.model.subtotal()) }
                    </div>
                </div>
                <div className="row t50-50">
                    <div className="title">Tax</div>
                    <div className="amount money">
                        { this.formatter(this.model.tax(0.08)) }
                    </div>
                </div>
                <div className="row t50-50">
                    <div className="title">Total</div>
                    <div className="amount money">
                        { this.formatter(this.model.total(0.08)) }
                    </div>
                </div>
            </div>
        );
    }

    render() {
        const items = [];
        let ni, isLast, error;

        for (ni = 0; ni < this.model.items.length; ni++) {
            isLast = ni === this.model.items.length - 1;

            this.assignKeys();

            items.push(
                <ManifestItem key={ this.model.items[ni]._key }
                    model={ this.model.items[ni] }
                    hidePrice={ this.props.hidePrice }
                    focusOn={ isLast ? this.focusOn : null }
                    fieldChange={ this.recalc.bind(this) }
                    onClose={ this.remove.bind(this, ni) } />);
        }

        if (this.model.errors && this.model.errors.required) {
            error = (
                <div className="row t100">
                    <div className="error">
                        { this.model.errors.required }
                    </div>
                </div>
            );
        }

        return (
            <div className="manifest">
                <div className="manifest-number">
                    <TextInput placeholder="Order Number"
                        label="Order ID"
                        value={ this.model.id }
                        update={ this.update.bind(this, 'id') } />
                </div>
                { this.getHeader() }
                { items }
                <ManifestItem key={ -1 }
                    model={ this.addItem }
                    hidePrice={ this.props.hidePrice }
                    fieldChange={ this.add.bind(this) } />
                { error }
                { this.getSubtotal() }
            </div>
        );
    }
}

export default Manifest;
