import React, { Component, PropTypes } from 'react';
import radium from 'radium';
import {
  goToLocation,
  fetchMostConnectedIfNeeded,
} from '../../action/core';
import CluedInProgress from '../generics/cluedinprogress.jsx';
import Widget from '../generics/widget.jsx';
import DomainUsers from '../users/DomainUsers.jsx';
import config from '../../config';
import { connect } from 'react-redux';
import {
  fetchActiveProvidersIfNeeded,
  skipBusy,
} from '../../action/provider';
import {
  fetchUsersIfNeeded,
  fetchPotentialUsersIfNeeded,
} from '../../action/user';
import {
  shouldFetchBoardingIfNeeded,
  fetchAllInvitations,
  removeOnBoarding,
  getOnBoardingState,
} from '../../action/boarding';
import { FormattedMessage, FormattedHTMLMessage } from 'react-intl';
import RaisedButton from 'material-ui/RaisedButton';
import ArrowUp from 'material-ui/svg-icons/hardware/keyboard-arrow-up';
import ArrowDown from 'material-ui/svg-icons/hardware/keyboard-arrow-down';
import onBoardingStyle from './OnBoarding.style.js';
import theme from '../../theme/index';

export class OnBoarding extends Component {

  static propTypes = {
    dispatch: PropTypes.func,
  };

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

  componentWillMount() {
    const {
      org,
    } = this.props;

    this.props.dispatch(fetchActiveProvidersIfNeeded());
    this.props.dispatch(fetchUsersIfNeeded());
    this.props.dispatch(fetchMostConnectedIfNeeded());
    this.props.dispatch(fetchPotentialUsersIfNeeded());
    this.props.dispatch(shouldFetchBoardingIfNeeded(org));
    this.props.dispatch(fetchAllInvitations(org));
    this.props.dispatch(getOnBoardingState());
  }

  componentDidUpdate() {
    let step = this.getStep();

    if ((!this.isBusy() || (step !== 1 && step !== 3)) && this.mainContent && this.state.isOpen) {
      setTimeout(function () {
        if (this.mainContent.classList.contains('cluedIn_hide_slide')) {
          this.mainContent.classList.remove('cluedIn_hide_slide');
          this.mainContent.classList.add('cluedIn_show_slide');
        }
      }.bind(this), 3000);
    }
  }

  getTitle(step) {
    switch (step) {
      case 1:
        return (
          <span><FormattedMessage id="OnBoarding.Step1.Title"/></span>
        );
      case 2:
        return (
          <span><FormattedMessage id="OnBoarding.Step2.Title"/></span>
        );
      case 3:
        return (
          <span><FormattedMessage id="OnBoarding.Step3.Title"/></span>
        );
      case 4:
        return (
          <span><FormattedMessage id="OnBoarding.Step4.Title"/></span>
        );
      case 5:
        return (
          <span><FormattedMessage id="OnBoarding.Step5.Title"/></span>
        );
      default:
        return (
          <span><FormattedMessage id="OnBoarding.Step0.Title"/></span>
        );
    }
  }

  getMenu(step) {
    let isActiveStep0 = (step === 0) ? 'active' : '';
    let isActiveStep1 = (step === 1) ? 'active' : '';
    let isActiveStep2 = (step === 2) ? 'active' : '';
    let isActiveStep3 = (step === 3) ? 'active' : '';
    let isActiveStep4 = (step === 4) ? 'active' : '';

    isActiveStep0 = (step > 0) ? 'done' : isActiveStep0;
    isActiveStep1 = (step > 1) ? 'done' : isActiveStep1;
    isActiveStep2 = (step > 2) ? 'done' : isActiveStep2;
    isActiveStep3 = (step > 3) ? 'done' : isActiveStep3;
    isActiveStep4 = (step > 4) ? 'done' : isActiveStep4;

    return (
      <ul className="cluedIn_progressive_menu cluedIn_m-b cluedIn_m-t">
        <li className={isActiveStep0}><a><FormattedMessage id="OnBoarding.Step0.Menu"/></a>
        </li>
        <li className={isActiveStep1}><a><FormattedMessage id="OnBoarding.Step1.Menu"/></a>
        </li>
        <li className={isActiveStep2}><a><FormattedMessage id="OnBoarding.Step2.Menu"/></a>
        </li>
        <li className={isActiveStep3}><a><FormattedMessage id="OnBoarding.Step3.Menu"/></a>
        </li>
        <li className={isActiveStep4}><a><FormattedMessage id="OnBoarding.Step4.Menu"/></a>
        </li>
      </ul>
    )
  }

  getSkipTutorial() {
    return (<div>
      <RaisedButton primary={true} onClick={this.step5Action.bind(this)} label="Skip Tutorial"></RaisedButton>
    </div>);
  }

  step0Action() {
    this.props.dispatch(goToLocation('addProvider'));
  }

  step2Action() {
    this.props.dispatch(goToLocation('addProvider'));
  }

  step1Action(searchTerm) {
    this.props.dispatch(goToLocation('goToSearch', searchTerm));
  }

  step3Action(entity) {
    this.props.dispatch(goToLocation('entity', entity));
  }

  step4Action() {
    this.props.dispatch(goToLocation('goToInviteUser'));
  }

  step5Action() {
    this.props.dispatch(removeOnBoarding('OnBoarding'));
  }

  progress(step) {
    var percentage = ((step / 5) * 100);
    var bigNumber = true;
    return (<div>
      <CluedInProgress withBigNumber={bigNumber} percentage={percentage}></CluedInProgress>
    </div>);
  }

  content(step) {
    const {connectedData, providers, potentialUsers} = this.props;

    switch (step) {
      case 1:
        var step1TranslatedValue = {
          name: providers[0].Name,
          searchQuery: connectedData[0].name
        };

        return (
          <div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              <FormattedHTMLMessage id="OnBoarding.Step1.Content"
                                    values={step1TranslatedValue}></FormattedHTMLMessage>

              <a style={[theme.link, theme.inlineBlock]}
                 onClick={this.step1Action.bind(this, connectedData[ 0 ].name)}
                 className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
                <span className="cluedIn_addon"><i className="fa fa-search"></i></span>
                                <span>
                                    <FormattedHTMLMessage id="OnBoarding.Step1.ContentAction"
                                                          values={step1TranslatedValue}/>
                                </span>
              </a>
            </div>
          </div>
        );
      case 2:
        return (
          <div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              <FormattedHTMLMessage id="OnBoarding.Step2.Content"/>
            </div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              In order to benefit from that:
            </div>
            <div className="cluedIn_text_zone">
              <a style={[theme.link, theme.inlineBlock]} onClick={this.step2Action.bind(this)}
                 className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
                                <span className="cluedIn_addon">
                                    <i className="fa fa-plug"></i>
                                </span>
                                <span>
                                    <FormattedMessage id="OnBoarding.Step2.ContentAction"/>
                                </span>
              </a>
            </div>
          </div>
        );
      case 3:
        let step3TranslatedValue = {
          name: providers[1].Name,
          connectedData: connectedData[0].name,
        };

        return (
          <div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              <FormattedHTMLMessage id="OnBoarding.Step3.Content"
                                    values={step3TranslatedValue}/>
            </div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              <a style={[theme.link, theme.inlineBlock]}
                 onClick={this.step3Action.bind(this, connectedData[ 0 ])}
                 className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
                <FormattedHTMLMessage id="OnBoarding.Step3.ContentAction"
                                      values={step3TranslatedValue}/>
              </a>
            </div>
          </div>
        );
      case 4:
        let potentialContent = '';
        let invitation = '';

        let potentialUsersWithEmail = potentialUsers.filter((domainUser) => {
          return domainUser.Properties && domainUser.Properties.MetadataDictionary && domainUser.Properties.MetadataDictionary['property-user.email'];
        });

        if (potentialUsersWithEmail && potentialUsersWithEmail.length > 0) {
          invitation = (
            <span><FormattedMessage id="OnBoarding.Step4.Content2"/></span>);
          potentialContent = (
            <div className="cluedIn_line"><DomainUsers inviteClick={this.inviteUserHandler.bind(this)}
                                                       potentialUsers={potentialUsersWithEmail}></DomainUsers>
            </div>);
        }

        return (
          <div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              <FormattedMessage id="OnBoarding.Step4.Content" />
              <br/>
              <br/>
            </div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              {invitation}
              {potentialContent}
            </div>
            <div className="cluedIn_text_zone">
              <a style={[theme.link, theme.inlineBlock]} onClick={this.step4Action.bind(this)}
                 className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
                <span className="cluedIn_addon">
                  <i className="fa fa-user-plus"></i>
                </span>
                <span>
                  <FormattedMessage id="OnBoarding.Step4.ContentAction" />
                </span>
              </a>
            </div>
          </div>
        );
      case 5:
        return (
          <div className="cluedIn_row">
            <div className="cluedIn_col s3">
              <img className="cluedIn_img_responsive" src={config.image.party} alt="Congratz!"/>
            </div>
            <div className="cluedIn_col s9">
              <div className="cluedIn_text_zone">
                <FormattedHTMLMessage id="OnBoarding.Step5.Content" />
              </div>
              <div className="cluedIn_text_zone">
                <a onClick={this.step5Action.bind(this)}
                   className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
                  <span className="cluedIn_addon">
                    <i className="fa fa-trash-o "></i>
                  </span>
                  <span>
                    <FormattedMessage id="OnBoarding.Step5.ContentAction" />
                  </span>
                </a>
              </div>
            </div>
          </div>
        );
      default:
        return (
          <div>
            <div className="cluedIn_text_zone cluedIn_highlightText">
              <FormattedMessage id="OnBoarding.Step0.Content"/>
              <br/>
            </div>
            <div className="cluedIn_text_zone">
              <a style={[theme.link, theme.inlineBlock]} onClick={this.step0Action.bind(this)}
                 className="cluedIn_btn-primary clued_In_btn_big cluedIn_pulse-button cluedIn_btn">
                <span className="cluedIn_addon">
                  <i className="fa fa-plug"></i>
                </span>
                <span>
                  <FormattedMessage id="OnBoarding.Step0.ContentAction"/>
                </span>
              </a>
            </div>
          </div>
        );
    }
  }

  step(number) {

    var title = this.getTitle(number);
    var menu = this.getMenu(number);
    var content = this.content(number);
    var progress = this.progress(number);

    let mainStyle = { display: 'block' };

    if (!this.state.isOpen) {
      mainStyle = { display: 'none' };
    }

    return (
      <div>
        <div className="cluedIn_row">
          <div className="cluedIn_col s12">
            <div className="cluedIn_title">
              <div className="textHeading h2">
                {title}
              </div>
            </div>
          </div>
        </div>
        <div style={mainStyle} ref={ (ref) => this.mainContent = ref }
             className="cluedIn_hide_slide cluedIn_m-t cluedIn_onBoarding_main">
          <div className="cluedIn_row">
            <div className="cluedIn_col s12">
              {menu}
            </div>
          </div>
          <div className="cluedIn_row">
            <div className="cluedIn_col s8">
              <div className="cluedIn_onBoarding_content">
                {content}
              </div>
            </div>
            <div className="cluedIn_col s4">
              {progress}
            </div>
          </div>
        </div>
      </div>
    );
  }

  isLoading() {
    let {isFetchingProvider, isFetchingUsers, isFetchingPotentialUsers, isFetchingBoardingInfo, isFetchingInvitations, isFetchingConnectedData} = this.props;
    return (isFetchingProvider || isFetchingUsers || isFetchingPotentialUsers || isFetchingBoardingInfo || isFetchingInvitations || isFetchingConnectedData);
  }

  getStep() {
    let {providers, hasSearched, hasVisitConnectedView, users, allInvitations} = this.props;
    let step = 0;

    if (providers && providers.length > 0) {
      if (hasSearched) {
        if (providers.length > 1) {
          if (hasVisitConnectedView) {
            if (users && users.length > 1 || allInvitations && allInvitations.length > 0) {
              step = 5;
            } else {
              step = 4;
            }
          } else {
            step = 3;
          }
        } else {
          step = 2;
        }
      } else {
        step = 1;
      }
    }

    if (step > 5) {
      step = 0;
    }

    return step;
  }

  inviteUserHandler(email, name) {
    this.props.dispatch(goToLocation('goToInviteUser', {email, name}));
  }

  toogle() {
    this.setState({
      isOpen: !this.state.isOpen,
    });
  }

  skipBusy() {
    this.props.dispatch(skipBusy());
  }

  isBusy() {
    const {isBusy, skipBusy} = this.props;

    return skipBusy ? false : isBusy;
  }

  openIntegrationReport() {
    var eventOpenIntegration = new Event('OpenIntegrationPanel');

    window.dispatchEvent(eventOpenIntegration);
  }

  render() {
    const {boardingState} = this.props;

    if (boardingState.done) {
      return <div></div>;
    }

    let content;
    let isLoading = this.isLoading();
    let step = this.getStep();

    if (!this.isBusy() && isLoading) {
      content = (<div>
        <div className="cluedIn_row">
          <div className="cluedIn_col s12">
            <div className="cluedIn_title">
              <div className="textHeading">
                <div className="cluedIn_title">
                  <div className="textHeading h2">
                    <div className="bounceball"></div>
                    <div className="bounceball"></div>
                    <div className="bounceball"></div>
                    Loading Tutorial. Let's help you get ready with your CluedIn account.
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>);
    }

    if (this.isBusy() && (step === 1 || step === 3)) {

      content = (
        <div>
          <div className="cluedIn_row">
            <div className="cluedIn_col s12">
              <div className="cluedIn_title">
                <div className="textHeading">
                  <div className="cluedIn_title">
                    <div className="textHeading h3">
                      <div style={ {float: 'left'} }>
                        <div className="bounceball"></div>
                      </div>
                      <div style={ {'paddingRight': '245px', paddingTop: '15px'} }>
                        We are currently crawling your integrations. You can check the status by
                        clicking on the <i style={ {marginLeft: '5px', marginRight: '5px'} }
                                           className="fa fa-plug"></i>
                      in the top right of your screen or simply
                        <a onClick={ this.openIntegrationReport.bind(this) }>click here.</a> Once
                      crawling has finished this tutorial will tell you what to do next.
                    </div>
                  </div>
                  <div style={ {marginTop: '10px'} }>
                    <div style={ {float: 'left', marginTop: '8px'} }>Don't want to wait?</div>
                    <div style={ {float: 'left', marginLeft:'15px'} }>
                      <RaisedButton
                        onClick={this.skipBusy.bind(this)}
                        primary={false}
                        label="Continue Tutorial Without Data">
                      </RaisedButton>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      )
    }

    if ((!this.isBusy() || (step !== 1 && step !== 3)) && !isLoading) {
      content = this.step(step);
    }

    let noScroll = true;

    let icon = <ArrowUp />;

    if (!this.state.isOpen) {
      icon = <ArrowDown />;
    }

    let expander = (
      <RaisedButton
        label=""
        onClick={this.toogle.bind(this)}
        style={{ position: 'absolute', right: '30px', top: '19px' }}
        icon={icon}
      />);

    let rightPosition = '135px';

    if (this.isBusy()) {
      expander = null;
      rightPosition = '30px';
    }

    return (
      <div>
        <div style={onBoardingStyle.onBoarding}>
          <Widget noScroll={noScroll}>
            <div style={{ position: 'absolute', right: rightPosition, top: '19px' }}>
              {this.getSkipTutorial()}
            </div>
            {expander}
            {content}
          </Widget>
        </div>
      </div>
    );
  }
}

function select(state) {
  return {
    providers: state.provider.providers,
    isFetchingProvider: state.provider.isFetching,
    isFetchingUsers: state.user.isFetching,
    users: state.user.users,
    hasSearched: (state.boarding.boardingInfo
      ? state.boarding.boardingInfo.hasSearched
      : false),
    hasVisitConnectedView: (state.boarding.boardingInfo
      ? state.boarding.boardingInfo.hasVisited
      : false),
    isFetchingBoardingInfo: state.boarding.isFetching,
    connectedData: state.core.connectedData,
    isFetchingConnectedData: state.core.isFetchingConnectedData,
    org: state.core.org,
    potentialUsers: state.user.potentialUsers,
    isFetchingPotentialUsers: state.user.isFetchingPotentialUsers,
    isFetchingInvitations: state.boarding.isFetchingInvitations,
    allInvitations: state.boarding.allInvitations,
    boardingState: state.boarding.state,
    allProviderStats: state.provider.allProviderStats,
    isBusy: state.provider.isBusy,
    skipBusy: state.provider.skipBusy,
  };
}

export default connect(select)(radium(OnBoarding));
