import React from 'react';
import PropTypes from 'prop-types';
import Remarkable from 'remarkable';

export default class Markdown extends React.Component {

  componentWillUpdate(nextProps, nextState) {
    if (nextProps.options !== this.props.options) {
      this.md = new Remarkable(nextProps.options);
    }
  }

  content() {
    // eslint-disable-next-line react/no-danger
    if (this.props.source) return <span dangerouslySetInnerHTML={{ __html: this.renderMarkdown(this.props.source) }} />;

    return React.Children.map(this.props.children, (child) => {
      if (typeof child === 'string') {
        // eslint-disable-next-line react/no-danger
        return <span dangerouslySetInnerHTML={{ __html: this.renderMarkdown(child) }} />;
      }
      return child;
    });
  }

  renderMarkdown(source) {
    if (!this.md) this.md = new Remarkable(this.props.options);
    if (this.props.renderInline) return this.md.renderInline(source);

    return this.md.render(source);
  }

  render() {
    const Container = this.props.container;

    if (this.props.noContainer) return this.content();

    return (
      <Container className={this.props.className} style={this.props.style}>
        {this.content()}
      </Container>
    );
  }

}

Markdown.propTypes = {
  container: PropTypes.string,
  noContainer: PropTypes.bool,
  renderInline: PropTypes.bool,
  /* eslint-disable react/forbid-prop-types */
  style: PropTypes.object,
  options: PropTypes.object,
  source: PropTypes.string,
  className: PropTypes.string
};

Markdown.defaultProps = {
  container: 'div',
  noContainer: false,
  renderInline: undefined,
  style: undefined,
  options: {},
  source: undefined,
  className: ''
};
