content: 'use strict';
  
  import React from 'react';
  import $ from 'jquery';
  import * as _ from 'lodash';
  
  import PortfolioStore from 'stores/PortfolioStore';
  import PortfolioActions from 'actions/PortfolioActions';
  
  class GridComponent extends React.Component {
    constructor(props) {
      super(props);
  
      this.state = PortfolioStore.getState();
    }
  
    componentDidMount() {
      PortfolioStore.listen(this.onChange.bind(this));
  
      PortfolioActions.fetchPortfolio();
  
      this.calcColumns();
  
      $(window).on('resize', _.debounce(this.calcColumns.bind(this), 150));
    }
  
    componentWillUnmount() {
      PortfolioStore.unlisten(this.onChange.bind(this));
    }
  
    onChange(state) {
      this.setState(state);
    }
  
    formatColumns(content) {
      var colCount = this.state.columns;
      var content = content || this.props.content;
      var columns = _.chunk(content, colCount);
      var rows = [];
  
      columns.forEach(function(items) {
        var row = {
          items: [],
          content: []
        };
  
        items.map(function(item) {
          row.items.push({title: item.title, img: item.img, colour: item.colour});
          row.content.push(item.description);
        });
  
        rows.push(row);
      });
  
      return rows;
    }
  
    calcColumns() {
      var breakpoints = [
        {
          cols: 1,
          mq: '(max-width: 480px)'
        },
        {
          cols: 2,
          mq: '(min-width: 481px) and (max-width: 767px)'
        },
        {
          cols: 3,
          mq: '(min-width: 768px) and (max-width: 991px)'
        },
        {
          cols: 4,
          mq: '(min-width: 992px)'
        }
      ];
  
      for (let i = 0; i < breakpoints.length; i++) {
        if (window.matchMedia(breakpoints[i].mq).matches) {
          if (this.state.columns !== breakpoints[i].cols) {
            PortfolioActions.updateColumns(breakpoints[i].cols);
          }
          break;
        }
      }
    }
  
    isElementInViewport(el) {
      var rect = el.getBoundingClientRect();
  
      return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
      );
    }
  
    expand(i, event) {
      var _this = this
        , $gridItem = $(event.currentTarget)
        , $expand = $gridItem.parents('.grid-row').find('[data-expand-key="' + i + '"]')
        , $row = $gridItem.parents('.grid-row')
        , $prevRow = $('.grid-row.active')
        , closingGridItem = false
        , transitionTiming = 700
        , direction = $prevRow.index() < $row.index() ? -1 : 1;
  
      // We're closing the current grid item
      if ($gridItem.hasClass('active')) {
        closingGridItem = true;
      }
  
      // If it's a grid item in a different row, allow old row to transition
      if (!$row.hasClass('active')) {
        $prevRow.removeClass('active');
      }
  
      // We always need to do this
      $('.grid-item.active').removeClass('active');
      $('.grid-item-expanded.active').removeClass('active');//.css('height', 0);
  
      // If we're closing current grid item, make sure we turn row off too
      // Then return early
      if (closingGridItem) {
        $row.removeClass('active');
        return;
      }
  
      // Open grid-item-expand and set grid item active
      $expand.addClass('active');//.css('height', $expand.find('.grid-item-expanded__copy').outerHeight(true));
      $gridItem.addClass('active');
  
      // Lock row transition off once other states are done
      if (!$row.hasClass('active')) {
        // Wait for transition to finish
        setTimeout(function() {
          $row.addClass('active');
          setTimeout(function() {
            // Scroll to new row if not mobile
            if (!window.matchMedia('(max-width: 480px)').matches) {
              // And not in viewport
              if (!_this.isElementInViewport($expand.get(0))) {
                $('html, body').animate({
                  scrollTop: $gridItem.offset().top
                }, 150);
              }
            }
          }, 50);
        }, transitionTiming);
      }
    }
  
    render() {
      let rows = [];
  
      let itemsComponent = (props) => {
        let stylesOuter = {
          backgroundImage: 'url(' + props.img + ')'
        };
        let stylesOverlay = {
          backgroundColor: props.colour
        };
        let stylesArrow = {
          borderTopColor: props.colour
        };
  
        return (
          <div onClick={this.expand.bind(this, props.target)} key={props.target} style={stylesOuter} className="grid-item" data-expand-target={props.target}>
            <div className="grid-item__inner">
              <div style={stylesOverlay} className="grid-item__overlay">
                <div className="v-align">
                  <div className="v-align__row">
                    <div dangerouslySetInnerHTML={{__html: props.title}} className="grid-item__title v-align__inner v-align__inner--top">
                    </div>
                  </div>
                  <div className="v-align__row">
                    <div className="v-align__inner v-align__inner--bottom">
                      <button className="grid-item__cta">
                        +
                      </button>
                    </div>
                  </div>
                </div>
                <div style={stylesArrow} className="grid-item__arrow">
                </div>
              </div>
            </div>
          </div>
        );
      };
  
      var contentComponent = (props) => {
        return (
          <div key={props.key} className="grid-item-expanded" data-expand-key={props.key}>
            <div className="grid-item-expanded__inner">
              <div dangerouslySetInnerHTML={{__html: props.description}} className="grid-item-expanded__copy">
              </div>
            </div>
          </div>
        );
      };
  
      if (this.state.portfolio) {
        let grid = this.formatColumns(this.state.portfolio.projects);
  
        grid.forEach(function(r, i){
          var items = [];
          var content =[];
  
          // Items
          r.items.forEach(function(item, i) {
            items.push(itemsComponent({
              target: i,
              title: item.title,
              img: item.img,
              colour: item.colour
            }));
          });
          // Content
          r.content.forEach(function(item, i) {
            content.push(contentComponent({ key: i, description: item }));
          });
  
          var rowComponent = (
            <div className="grid-row row" key={i}>
              {items}
              {content}
            </div>
          );
  
          // Rows
          rows.push(
            rowComponent
          );
        });
      }
  
      return (
        <div className="grid-component">
          {rows}
        </div>
      );
    }
  }
  
  GridComponent.displayName = 'GridComponent';
  
  // Uncomment properties you need
  // GridComponent.propTypes = {};
  // GridComponent.defaultProps = {};
  
  export default GridComponent;
  