import React from 'react';
import { debounce } from 'lodash';
import styled from 'styled-components';
import { AnimationTimer } from 'animation-timer';
import { Easer } from 'functional-easing';
import Icon from './Icon';

const Container = styled.div`
  border: ${({ theme }) => theme.accordion.border};
  overflow: hidden;
`;

const Label = styled.div`
  padding: ${({ theme }) => theme.accordion.padding};
  color: ${({ theme }) => theme.accordion.labelFG};
  font-family: ${({ theme }) => theme.accordion.labelFontFamily};
  font-size: ${({ theme }) => theme.accordion.labelFontSize};
  cursor: pointer;
  display: flex;
  flex-direction: row;
  user-select: none;
`;

const Content = styled.div`
  overflow: hidden;
`;

const ContentPadding = styled.div`
  padding: ${({ theme }) => theme.accordion.padding};
  padding-top: 0;
`;

const ModdedIcon = styled(Icon)`
  color: #666;
  margin: auto;
  transform: ${({ isCollapsed }) => isCollapsed ? 'rotate(0)' : 'rotate(90deg)'};
  transition: 0.2s all ease;

  &:after {
    padding-top: 0;
    padding-bottom: 0;
  }
`;

const LabelText = styled.span`
  margin: auto;
  flex: 1;
`;

const getComputedPaddingBottomPixels = (el) =>
  parseInt(window.getComputedStyle(el)['padding-bottom'].replace('px', ''), 10);

/**
 * Accordion works like a controllable component. Provide the
 * isCollapsed prop to control it, or don't to let it control itself.
 */
export default class Accordion extends React.Component {
  static propTypes = {
    label: React.PropTypes.node.isRequired,
    children: React.PropTypes.node.isRequired,
    isCollapsed: React.PropTypes.bool,
    onToggle: React.PropTypes.func,
  };

  static defaultProps = {
    isCollapsed: null,
    onToggle: () => {}, // no-op
  };

  constructor(props) {
    super(props);
    this.state = { internalIsCollapsed: true };
  }

  componentDidMount() {
    // on first mount, recalculate the natural size and setup without animation
    this.setContentCollapseState(false);
    // any time the window resizes, recalculate the natural size
    window.addEventListener('resize',
      debounce(this.setContentCollapseState.bind(this, false), 300),
    );
  }

  componentDidUpdate(prevProps, prevState) {
    // only animate if the collapsed state has changed.
    this.setContentCollapseState(prevProps.isCollapsed !== this.props.isCollapsed ||
      prevState.internalIsCollapsed !== this.state.internalIsCollapsed);
  }

  setContentCollapseState = (animate = true) => {
    const isCollapsed = this.calcIsCollapsed();
    const content = this._content;
    if (!content) {
      return;
    }
    const naturalHeight = content.scrollHeight;
    if (animate) {
      const easer = new Easer().using('cubic');
      new AnimationTimer()
        .duration(200)
        .on('tick', easer((percent) => {
          const directionalPercent = isCollapsed ? 1.0 - percent : percent;
          content.style.height = `${naturalHeight * directionalPercent}px`;
        })).play();
    } else {
      content.style.height = isCollapsed ? 0 : naturalHeight;
    }
  };

  handleToggle = () => {
    if (this.props.onToggle) {
      this.props.onToggle(this.calcIsCollapsed());
    }
    this.setState({ internalIsCollapsed: !this.state.internalIsCollapsed });
  };

  calcIsCollapsed = () => {
    const { isCollapsed } = this.props;
    const { internalIsCollapsed } = this.state;
    if (isCollapsed === null) {
      return internalIsCollapsed;
    }

    return isCollapsed;
  };

  renderContent = () => (
    <Content
      innerRef={(el) => { this._content = el; }}
      isCollapsed={this.calcIsCollapsed()}
    >
      <ContentPadding>
        {this.props.children}
      </ContentPadding>
    </Content>
    );

  render() {
    const isCollapsed = this.calcIsCollapsed();
    return (
      <Container>
        <Label onClick={this.handleToggle}>
          <ModdedIcon isCollapsed={isCollapsed} name="forward" size={21} />
          <LabelText>{this.props.label}</LabelText>
        </Label>
        {this.renderContent()}
      </Container>
    );
  }
}

@@ -1134,137 +1134,8 @@
 %60;%0A%0A
-const getComputedPaddingBottomPixels = (el) =%3E%0A  parseInt(window.getComputedStyle(el)%5B'padding-bottom'%5D.replace('px', ''), 10);%0A%0A
 /**%0A

fix code style