'use strict';

import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {
  requireNativeComponent,
  TouchableHighlight,
  View,
  NativeModules,
  findNodeHandle,
} from 'react-native';

const ToolTipMenu = NativeModules.ToolTipMenu;
const RCTToolTipText = requireNativeComponent('RCTToolTipText', null);

export default class ToolTip extends PureComponent {
    static propTypes = {
        actions: PropTypes.arrayOf(PropTypes.shape({
            text: PropTypes.string.isRequired,
            onPress: PropTypes.func
        })),
        arrowDirection: PropTypes.oneOf(['up', 'down', 'left', 'right', 'default']),
        longPress: PropTypes.bool,
        onHide: PropTypes.func,
        onShow: PropTypes.func,
        ...TouchableHighlight.propTypes
    };

    static defaultProps = {
        arrowDirection: 'default',
        onHide: () => true,
        onShow: () => true
    };

    showMenu = () => {
        ToolTipMenu.show(findNodeHandle(this.refs.toolTipText), this.getOptionTexts(), this.props.arrowDirection);
        this.props.onShow();
    };

    hideMenu = () => {
        ToolTipMenu.hide();
        this.props.onHide();
    };

    getOptionTexts = () => {
        return this.props.actions.map((option) => option.text);
    };

    // Assuming there is no actions with the same text
    getCallback = (optionText) => {
        const selectedOption = this.props.actions.find((option) => option.text === optionText);

        if (selectedOption) {
            return selectedOption.onPress;
        }

        return null;
    };

    getTouchableHighlightProps = () => {
        const props = {};

        Object.keys(TouchableHighlight.propTypes).forEach((key) => props[key] = this.props[key]);

        if (this.props.longPress) {
            props.onLongPress = this.showMenu;
        } else {
            props.onPress = this.showMenu;
        }

        return props;
    };

    handleToolTipTextChange = (event) => {
        const callback = this.getCallback(event.nativeEvent.text);
        if (callback) {
            callback(event);
        }
    };

    handleBlurToolTip = () => {
        this.hideMenu();
    };

    render() {
        return (
            <RCTToolTipText ref='toolTipText' onChange={this.handleToolTipTextChange} onBlur={this.handleBlurToolTip}>
              <TouchableHighlight
                  {...this.getTouchableHighlightProps()}
              >
                <View>
                    {this.props.children}
                </View>
              </TouchableHighlight>
            </RCTToolTipText>
        );
    }
}