var virt = require("@nathanfaucett/virt"),
    extend = require("@nathanfaucett/extend"),
    arrayMap = require("@nathanfaucett/array-map"),
    propTypes = require("@nathanfaucett/prop_types"),
    Menu = require("virt-ui-menu"),
    Popover = require("virt-ui-popover"),
    ListItem = require("virt-ui-list_item");


var isView = virt.View.isView,
    MenuItemPrototype;


module.exports = MenuItem;


function MenuItem(props, children, context) {
    var _this = this;

    virt.Component.call(this, props, children, context);

    this.state = {
        open: false
    };

    this.cloneMenuItem = function(item) {
        return _this.__cloneMenuItem(item);
    };
    this.onTouchTap = function(e) {
        return _this.__onTouchTap(e);
    };
    this.onRequestClose = function() {
        return _this.__onRequestClose();
    };
}
virt.Component.extend(MenuItem, "virt-ui-MenuItem");

MenuItem.propTypes = {
    checked: propTypes.bool,

    desktop: propTypes.bool,
    disabled: propTypes.bool,

    focusState: propTypes.oneOf([
        "none",
        "focused",
        "keyboard-focused"
    ]),

    innerDivStyle: propTypes.object,

    insetChildren: propTypes.bool,
    leftIcon: propTypes.object,

    menuItems: propTypes.object,

    onTouchTap: propTypes.func,

    rightIcon: propTypes.object,
    secondaryText: propTypes.object,

    style: propTypes.object,
    value: propTypes.any
};

MenuItem.contextTypes = {
    theme: propTypes.implement({
        fontFamily: propTypes.string,
        palette: propTypes.implement({
            primaryColor: propTypes.string,
            secondaryColor: propTypes.string,
            disabledColor: propTypes.string,
            primaryTextColor: propTypes.string,
            secondaryTextColor: propTypes.string,
            disabledTextColor: propTypes.string
        }).isRequired
    }).isRequired
};

MenuItem.defaultProps = {
    checked: false,
    desktop: false,
    disabled: false,
    focusState: "none",
    insetChildren: false
};

MenuItemPrototype = MenuItem.prototype;

MenuItemPrototype.componentDidMount = function() {
    this.__applyFocusState();
};

MenuItemPrototype.componentWillUnmount = function() {
    if (this.state.open) {
        this.setState({
            open: false
        });
    }
};

MenuItemPrototype.componentWillReceiveProps = function(nextProps) {
    if (this.state.open && nextProps.focusState === "none") {
        this.__onRequestClose();
    }
};

MenuItemPrototype.__applyFocusState = function() {
    if (this.refs.listItem) {
        this.refs.listItem.applyFocusState(this.props.focusState);
    }
};

MenuItemPrototype.__cloneMenuItem = function(item) {
    var _this = this;

    return (
        virt.cloneView(item, {
            onTouchTap: function(e) {
                if (!item.props.menuItems) {
                    _this.__onRequestClose();
                }
                if (item.props.onTouchTap) {
                    item.props.onTouchTap(e);
                }
            },
            onRequestClose: this.__onRequestClose
        })
    );
};

MenuItemPrototype.__onTouchTap = function(e) {
    e.preventDefault();

    this.setState({
        open: true
    });

    if (this.props.onTouchTap) {
        this.props.onTouchTap(e);
    }
};

MenuItemPrototype.__onRequestClose = function() {
    this.setState({
        open: false
    });
};

MenuItemPrototype.componentDidUpdate = function() {
    this.__applyFocusState();
};

MenuItemPrototype.getStyles = function() {
    var props = this.props,

        disabled = props.disabled,
        desktop = props.desktop,

        leftIcon = props.leftIcon,
        insetChildren = props.insetChildren,
        checked = props.checked,

        leftIndent = desktop ? 64 : 72,
        sidePadding = desktop ? 24 : 16,

        palette = this.context.theme.palette,

        styles = {
            root: {
                color: disabled ? palette.disabledColor : palette.primaryTextColor,
                lineHeight: desktop ? "32px" : "48px",
                fontSize: (desktop ? 15 : 16) + "px",
                whiteSpace: "nowrap"
            },
            innerDivStyle: {
                paddingLeft: (leftIcon || insetChildren || checked ? leftIndent : sidePadding) + "px",
                paddingRight: sidePadding + "px"
            },
            secondaryText: {
                order: 2,
                overflow: "hidden",
                textOverflow: "ellipsis",
                whiteSpace: "nowrap"
            },
            leftIconDesktop: {
                margin: "0px",
                left: "24px",
                top: "4px"
            },
            rightIconDesktop: {
                margin: "0px",
                right: "24px",
                top: "4px",
                fill: props.rightIconDesktopFill || palette.disabledColor
            }
        };

    return styles;
};

MenuItemPrototype.render = function() {
    var state = this.state,
        props = this.props,
        children = this.children.slice(),

        style = props.style,
        leftIcon = props.leftIcon,
        menuItems = props.menuItems,
        secondaryText = props.secondaryText,
        rightIcon = props.rightIcon,
        desktop = props.desktop,
        insetChildren = props.insetChildren,

        styles = this.getStyles(),

        leftIconView = leftIcon ? leftIcon : props.checked ? "checked" : null,

        rightIconView, secondaryTextIsAnView;

    if (leftIconView && desktop) {
        leftIconView = virt.cloneView(leftIconView, {
            style: extend(styles.leftIconDesktop, leftIconView.props.style)
        });
    }
    if (rightIcon) {
        rightIconView = virt.cloneView(rightIcon, {
            style: desktop ? extend(styles.rightIconDesktop, rightIcon.props.style) : rightIcon.props.style
        });
    }

    if (secondaryText) {
        secondaryTextIsAnView = isView(secondaryText);

        children[children.length] = (
            secondaryTextIsAnView ?
            virt.cloneView(secondaryText, {
                style: secondaryTextIsAnView ? extend(styles.secondaryText, secondaryText.props.style) : null
            }) :
            virt.createView("div", {
                    style: styles.secondaryText
                },
                secondaryText
            )
        );
    }

    if (menuItems) {
        children[children.length] = (
            virt.createView(Popover, {
                    anchorOrigin: {
                        horizontal: "left",
                        vertical: "top"
                    },
                    open: state.open,
                    onRequestClose: this.onRequestClose
                },
                virt.createView(Menu, {
                        desktop: desktop,
                        disabled: props.disabled,
                        style: nestedMenuStyle
                    },
                    arrayMap(menuItems, this.cloneMenuItem)
                )
            )
        );
    }

    return (
        virt.createView(ListItem, extend({}, props, {
                onTouchTap: this.onTouchTap,
                disabled: props.disabled,
                innerDivStyle: extend(styles.innerDivStyle, props.innerDivStyle),
                insetChildren: insetChildren,
                leftIcon: leftIconView,
                ref: "listItem",
                rightIcon: rightIconView,
                style: extend(styles.root, style)
            }),
            children
        )
    );
};
