text: import PropTypes from 'prop-types'
  import React, { Component } from 'react'
  import {
    Animated,
    StyleSheet,
    TouchableOpacity,
    TouchableWithoutFeedback,
    View,
  } from 'react-native'
  import ActionButtonItem from './ActionButtonItem'
  
  const alignMap = {
    center: {
      alignItems: 'center',
      justifyContent: 'flex-end',
      startDegree: 180,
      endDegree: 360,
    },
  
    left: {
      alignItems: 'flex-start',
      justifyContent: 'flex-end',
      startDegree: 270,
      endDegree: 360,
    },
  
    right: {
      alignItems: 'flex-end',
      justifyContent: 'flex-end',
      startDegree: 180,
      endDegree: 270,
    },
  }
  
  export default class ActionButton extends Component {
    constructor(props) {
      super(props)
      this.state = {
        active: props.active,
        anim: new Animated.Value(props.active ? 1 : 0),
      }
  
      this.timeout = null
    }
  
    componentWillUnmount() {
      clearTimeout(this.timeout)
    }
  
    getActionButtonStyle() {
      return [styles.actionBarItem, this.getButtonSize()]
    }
  
    getActionContainerStyle() {
      const { alignItems, justifyContent } = alignMap[this.props.position]
      return [
        styles.overlay,
        styles.actionContainer,
        {
          alignItems,
          justifyContent,
        },
      ]
    }
    getActionsStyle() {
      return [this.getButtonSize()]
    }
  
    getButtonSize() {
      return {
        width: this.props.size,
        height: this.props.size,
      }
    }
  
    animateButton() {
      if (this.state.active) {
        this.reset()
        return
      }
  
      Animated.spring(this.state.anim, {
        toValue: 1,
        duration: 250,
      }).start()
  
      this.setState({ active: true })
    }
  
    reset() {
      Animated.spring(this.state.anim, {
        toValue: 0,
        duration: 250,
      }).start()
  
      setTimeout(() => {
        this.setState({ active: false })
      }, 250)
    }
  
    renderButton() {
      return (
        <View
          style={[
            this.getActionButtonStyle(),
  
            {
              marginBottom: this.props.centerButtonBottomMargin,
              marginLeft: this.props.centerButtonLeftMargin,
            },
          ]}
        >
          <TouchableOpacity
            activeOpacity={0.85}
            onLongPress={this.props.onLongPress}
            onPress={() => {
              this.props.onPress()
              if (this.props.children) {
                this.animateButton()
              }
            }}
          >
            <Animated.View
              style={[
                styles.btn,
                {
                  width: this.props.size,
                  height: this.props.size,
                  borderRadius: this.props.size / 2,
                  backgroundColor: this.state.anim.interpolate({
                    inputRange: [0, 1],
                    outputRange: [this.props.buttonColor, this.props.btnOutRange],
                  }),
                  transform: [
                    {
                      scale: this.state.anim.interpolate({
                        inputRange: [0, 1],
                        outputRange: [1, this.props.outRangeScale],
                      }),
                    },
                    {
                      rotate: this.state.anim.interpolate({
                        inputRange: [0, 1],
                        outputRange: ['0deg', this.props.degrees + 'deg'],
                      }),
                    },
                  ],
                },
              ]}
            >
              {this.renderButtonIcon()}
            </Animated.View>
          </TouchableOpacity>
        </View>
      )
    }
  
    renderButtonIcon() {
      if (this.props.icon) {
        return this.props.icon
      }
  
      return (
        <Animated.Text
          style={[
            styles.btnText,
            {
              color: this.state.anim.interpolate({
                inputRange: [0, 1],
                outputRange: [
                  this.props.buttonTextColor,
                  this.props.btnOutRangeTxt,
                ],
              }),
            },
          ]}
        >
          +
        </Animated.Text>
      )
    }
  
    renderActions() {
      if (!this.state.active) return null
      const startDegree =
        this.props.startDegree || alignMap[this.props.position].startDegree
      const endDegree =
        this.props.endDegree || alignMap[this.props.position].endDegree
      const startRadian = (startDegree * Math.PI) / 180
      const endRadian = (endDegree * Math.PI) / 180
  
      const childrenCount = React.Children.count(this.props.children)
      let offset = 0
      if (childrenCount !== 1) {
        offset = (endRadian - startRadian) / (childrenCount - 1)
      }
  
      return React.Children.map(this.props.children, (button, index) => {
        return (
          <View
            pointerEvents="box-none"
            style={[
              this.getActionContainerStyle(),
              /* { marginBottom: Platform.OS === 'ios' ? 35 : 20, marginLeft: 10 } */
            ]}
          >
            <ActionButtonItem
              key={index}
              position={this.props.position}
              anim={this.state.anim}
              size={this.props.itemSize}
              radius={this.props.radius}
              angle={startRadian + index * offset}
              btnColor={this.props.btnOutRange}
              {...button.props}
              onPress={() => {
                if (this.props.autoInactive) {
                  this.timeout = setTimeout(() => {
                    this.reset()
                  }, 200)
                }
                button.props.onPress()
              }}
              actionItemBottom={this.props.actionItemBottom}
            />
          </View>
        )
      })
    }
  
    render() {
      let backdrop
      if (this.state.active) {
        backdrop = (
          <TouchableWithoutFeedback
            style={styles.overlay}
            onPress={() => {
              this.reset()
              this.props.onOverlayPress()
            }}
          >
            <Animated.View
              style={{
                backgroundColor: this.props.bgColor,
                opacity: this.state.anim,
                flex: 1,
              }}
            >
              {this.props.backdrop}
            </Animated.View>
          </TouchableWithoutFeedback>
        )
      }
      return (
        <View pointerEvents="box-none" style={styles.overlay}>
          {backdrop}
  
          {this.props.children && this.renderActions()}
          <View pointerEvents="box-none" style={[this.getActionContainerStyle()]}>
            {this.renderButton()}
          </View>
        </View>
      )
    }
  }
  
  ActionButton.Item = ActionButtonItem
  
  ActionButton.propTypes = {
    active: PropTypes.bool,
    bgColor: PropTypes.string,
    buttonColor: PropTypes.string,
    buttonTextColor: PropTypes.string,
    size: PropTypes.number,
    itemSize: PropTypes.number,
    autoInactive: PropTypes.bool,
    onPress: PropTypes.func,
    onOverlayPress: PropTypes.func,
    backdrop: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
    startDegree: PropTypes.number,
    endDegree: PropTypes.number,
    radius: PropTypes.number,
    children: PropTypes.node,
    position: PropTypes.oneOf(['left', 'center', 'right']),
  }
  
  ActionButton.defaultProps = {
    active: false,
    bgColor: 'transparent',
    buttonColor: 'rgba(0,0,0,1)',
    buttonTextColor: 'rgba(255,255,255,1)',
    position: 'center',
    outRangeScale: 1,
    autoInactive: true,
    onPress: () => {},
    onOverlayPress: () => {},
    backdrop: false,
    degrees: 135,
    size: 63,
    itemSize: 36,
    radius: 100,
    btnOutRange: 'rgba(0,0,0,1)',
    btnOutRangeTxt: 'rgba(255,255,255,1)',
  }
  
  const styles = StyleSheet.create({
    overlay: {
      position: 'absolute',
      bottom: 0,
      left: 0,
      right: 0,
      top: 0,
      backgroundColor: 'transparent',
    },
    actionContainer: {
      flexDirection: 'column',
      padding: 10,
    },
    actionBarItem: {
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: 'transparent',
    },
    btn: {
      justifyContent: 'center',
      alignItems: 'center',
      shadowOpacity: 0.3,
      shadowOffset: {
        width: 0,
        height: 1,
      },
      shadowColor: '#444',
      shadowRadius: 1,
    },
    btnText: {
      marginTop: -4,
      fontSize: 24,
      backgroundColor: 'transparent',
      position: 'relative',
    },
  })
  