import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import DocumentTitle from 'react-document-title';
import {FormattedMessage} from 'react-intl';
import classNames from 'classnames';
import {Row, Col, Icon, Affix, Tooltip} from 'antd';
import {getChildren} from 'jsonml.js/lib/utils';
import cheerio from 'cheerio';
import Demo from './Demo';
import {fetchHtml} from '../service';

export default class ComponentDoc extends React.Component {
  static contextTypes = {
    intl: PropTypes.object
  };

  constructor(props) {
    super(props);

    this.state = {
      expandAll: false,
      visibleAll: process.env.NODE_ENV !== 'production'
    };
  }

  handleExpandToggle = () => {
    const {expandAll} = this.state;
    this.setState({
      expandAll: !expandAll
    });
  };

  componentDidMount() {
    this.fetchMoreApi(this.props.location.pathname);
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevProps.location.pathname !== this.props.location.pathname) {
      this.fetchMoreApi(this.props.location.pathname);
    }
  }

  fetchMoreApi(url) {
    const tempUrl = url.endsWith('/') ? url.substring(0, url.length - 1) : url;
    fetchHtml(`/docs/${tempUrl.replace(/\//, '_')}.html`)
      .then((payload) => {
        if (this.moreApi) {
          const $ = cheerio.load(payload);
          const api = $('.markdown.api-container').children();
          let content = '';
          if (api && api.length > 0) {
            api.each(function(i, elem) {
              if (elem.attribs.id !== 'API') {
                content += $.html(this);
              }
            });
          }
          if (content !== '') {
            const moreApiNode = ReactDOM.findDOMNode(this.moreApi);
            if (moreApiNode) {
              moreApiNode.innerHTML = content;
            }
          }
        }
      })
      .catch((error) => {
        const moreApiNode = ReactDOM.findDOMNode(this.moreApi);
        if (moreApiNode) {
          moreApiNode.innerHTML = '';
        }
      });
  }

  render() {
    const {props} = this;
    const {doc, location, setIframeTheme, theme} = props;
    const {content, meta} = doc;
    const {
      intl: {locale}
    } = this.context;
    const demos = Object.keys(props.demos).map(key => props.demos[key]);
    const {expandAll, visibleAll} = this.state;

    const isSingleCol = meta.cols === 1;
    const leftChildren = [];
    const rightChildren = [];
    let showedDemo = demos.some(demo => demo.meta.only)
      ? demos.filter(demo => demo.meta.only)
      : demos.filter(demo => demo.preview);

    if (!visibleAll) {
      showedDemo = showedDemo.filter(item => !item.meta.debug);
    }

    showedDemo
      .sort((a, b) => a.meta.order - b.meta.order)
      .forEach((demoData, index) => {
        const demoElem = (
          <Demo
            {...demoData}
            key={demoData.meta.filename}
            utils={props.utils}
            expand={expandAll}
            location={location}
            theme={theme}
            setIframeTheme={setIframeTheme}
          />
        );
        if (index % 2 === 0 || isSingleCol) {
          leftChildren.push(demoElem);
        } else {
          rightChildren.push(demoElem);
        }
      });
    const expandTriggerClass = classNames({
      'code-box-expand-trigger': true,
      'code-box-expand-trigger-active': expandAll
    });

    const jumper = showedDemo.map((demo) => {
      const {title} = demo.meta;
      const localizeTitle = title[locale] || title;
      return (
        <li key={demo.meta.id} title={localizeTitle}>
          <a href={`#${demo.meta.id}`}>{localizeTitle}</a>
        </li>
      );
    });

    const {title, subtitle, filename} = meta;
    return (
      <DocumentTitle title={`${subtitle || ''} ${title[locale] || title} - DPL`}>
        <article>
          <Affix className='toc-affix' offsetTop={16}>
            <ul id='demo-toc' className='toc'>
              {jumper}
            </ul>
          </Affix>
          <section className='markdown'>
            <h1>
              {title[locale] || title}
              {!subtitle ? null : <span className='subtitle'>{subtitle}</span>}
            </h1>
            {props.utils.toReactComponent(
              ['section', {className: 'markdown'}].concat(getChildren(content))
            )}
            <h2>
              <FormattedMessage id='app.component.examples' />
              <Tooltip
                title={(
                  <FormattedMessage
                    id={`app.component.examples.${expandAll ? 'collpse' : 'expand'}`}
                  />
                )}
              >
                <Icon
                  type={`${expandAll ? 'appstore' : 'appstore-o'}`}
                  className={expandTriggerClass}
                  onClick={this.handleExpandToggle}
                />
              </Tooltip>
            </h2>
          </section>
          <Row gutter={16}>
            <Col
              span={isSingleCol ? 24 : 12}
              className={isSingleCol ? 'code-boxes-col-1-1' : 'code-boxes-col-2-1'}
            >
              {leftChildren}
            </Col>
            {isSingleCol ? null : (
              <Col className='code-boxes-col-2-1' span={12}>
                {rightChildren}
              </Col>
            )}
          </Row>
          {props.utils.toReactComponent(
            [
              'section',
              {
                className: 'markdown api-container'
              }
            ].concat(getChildren(doc.api || ['placeholder']))
          )}
          <div>
            <h2><FormattedMessage id='app.api.more' /></h2>
            <section className='markdown api-container' ref={instance => this.moreApi = instance} />
          </div>
        </article>
      </DocumentTitle>
    );
  }
}
