import React, { Component } from 'react';
import PropTypes from 'prop-types';

const propTypes = {
  elementID: PropTypes.string,
  onloadCallback: PropTypes.func,
  verifyCallback: PropTypes.func,
  expiredCallback: PropTypes.func,
  render: PropTypes.oneOf(['onload', 'explicit']),
  sitekey: PropTypes.string
};

const defaultProps = {
  elementID: 'g-recaptcha',
  onloadCallback: undefined,
  verifyCallback: undefined,
  expiredCallback: undefined,
  render: 'onload'
};

const isReady = () => typeof window !== 'undefined'
  && typeof window.grecaptcha !== 'undefined'
  && typeof window.grecaptcha.render === 'function';

let readyCheck;
export default class GRecaptcha extends Component {

  constructor(props) {
    super(props);
    this._renderGrecaptcha = this._renderGrecaptcha.bind(this);
    this.state = {
      ready: isReady(),
      widget: null,
    };
  }

  componentDidMount() {
    if (this.state.ready) {
      this._renderGrecaptcha();
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const { render, onloadCallback } = this.props;

    if (render === 'explicit' && onloadCallback && this.state.ready && !prevState.ready) {
      this._renderGrecaptcha();
    }
  }
  
  componentWillMount() {
    const { render } = this.props;
    const s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.defer = true;
    s.src = 'https://www.google.com/recaptcha/api.js?render=' + render;
    document.head.appendChild(s);
    if (!this.state.ready && typeof window !== 'undefined') {
        readyCheck = setInterval(this._updateReadyState.bind(this), 500);
    }
  }

  _updateReadyState() {
    if (isReady()) {
      this.setState({
        ready: true,
        grecaptcha: window.grecaptcha
      });
      clearInterval(readyCheck);
    }
  }

  _renderGrecaptcha() {
    let widget = this.state.grecaptcha.render(this.props.elementID, {
      sitekey: this.props.sitekey,
      callback: (this.props.verifyCallback) ? this.props.verifyCallback : undefined,
      'expired-callback': (this.props.expiredCallback) ? this.props.expiredCallback : undefined,
    });

    this.setState({
        widget: widget
    });

    if (this.props.onloadCallback) {
      this.props.onloadCallback();
    }
  }

  render() {
    return (
      <div 
        id={this.props.elementID}
        data-sitekey={this.props.sitekey}
      />
    );
  }
}
GRecaptcha.propTypes = propTypes;
GRecaptcha.defaultProps = defaultProps;