import React from 'react';
import { inject, observer } from 'mobx-react';
import { RouteComponentProps } from 'react-router-dom';
import { get, groupBy, map } from 'lodash';
import { ContentContainer, Portrait, ScrollToTop } from '../../components';
import { UserStore } from '../../stores/user-store';
import { CharacterService, UserService } from '../../services';
import { CharacterModel } from '../../model';
import './user-account.scss';

interface Props extends RouteComponentProps<any> {
  userStore?: UserStore;
}

interface State {
  characters: {[realm: string]: CharacterModel[]};
  selectedRealm?: string;
  selectedCharIndex: number;
  selectedAvatarIndex: number;
  insufficientScope?: boolean;
  noCharacters: boolean;
  region: 'us' | 'eu';
}

@inject('userStore')
@observer
export class UserAccount extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      characters: {},
      noCharacters: false,
      selectedCharIndex: 0,
      selectedAvatarIndex: 0,
      region: 'us', // default to US api
    };
  }

  componentDidMount() {
    // only load characters if user is battenet user
    if (get(this.props, 'userStore.user.access_token')) {
      this.getCharacters();
    }
  }

  private selectedCharacter(): CharacterModel {
    const { selectedRealm, selectedCharIndex } = this.state;
    const char = get(this.state, `characters[${selectedRealm}][${selectedCharIndex}]`);
    return char;
  }

  async getCharacters() {
    const { region } = this.state;
    try {
      const res = await UserService.getCharacters({ region });
      if (res.characters) {
        if (res.characters.length === 0) {
          this.setState({ noCharacters: true });
          return;
        }
        const characters = groupBy(res.characters, 'realm');
        this.setState({
          characters,
          selectedRealm: res.characters[0].realm,
          insufficientScope: false,
          noCharacters: false,
        });
      } else {
        this.setState({ insufficientScope: true });
      }
    } catch (e) {
      console.error(e);
    }
  }

  onRealmSelect(event: any) {
    this.setState({
      selectedRealm: event.target.value,
      selectedCharIndex: 0,
      selectedAvatarIndex: 0,
    });
  }

  onCharSelect(event: any) {
    this.setState({
      selectedCharIndex: event.target.value as any,
      selectedAvatarIndex: 0,
    });
  }

  onAvatarSelect(selectedAvatarIndex: number) {
    this.setState({ selectedAvatarIndex });
  }

  private async onSave() {
    const { name, guild, realm } = this.selectedCharacter();
    const selectedAvatar = this.selectedCharacter().avatarList![this.state.selectedAvatarIndex].title;
    const charClass = CharacterService.getClass(this.selectedCharacter().class);
    const { region } = this.state;
    const data = {
      region,
      character_name: name,
      character_class: charClass.name,
      character_guild: guild,
      character_realm: realm,
      character_avatar: selectedAvatar,
    };

    await UserService.saveCharacter(data);
  }

  private logout() {
    this.props.userStore!.resetUser();
    window.location.pathname = '/';
  }

  private renderScopeError() {
    return (
      <div>
        <p>
          To set your default character
          we need access to your WoW profile.
        </p>
        <ul>
          <li><a href="https://us.battle.net/account/management/authorizations.html"
            target="_blank">Navigate to your Battle.net Authorized Applications</a></li>
          <li>Remove Classic WoW Forums</li>
          <li>Log out and back into Classic WoW Forums</li>
          <li>Grant Classic WoW Forums access to your WoW profile</li>
        </ul>
      </div>
    );
  }

  renderDropDowns() {
    if (!this.selectedCharacter()) {
      return <div></div>;
    }
    return (
      <div>
        <h2>Set your default character</h2>
        <div style={{ margin: '0 10px 10px 0', display: 'inline-block' }}>
          <select value={this.selectedCharacter().realm}
            onChange={event => this.onRealmSelect(event)}>
            {map(this.state.characters, (_, realm: string) => {
              return <option key={`realm${realm}`}>{realm}</option>;
            })}
          </select>
          <select style={{ marginLeft: '5px' }}
            onChange={event => this.onCharSelect(event)}>
            {map(this.state.characters[this.state.selectedRealm!], (value, index) => {
              return <option key={this.state.selectedRealm! + index} value={index}>{value.name}</option>;
            })}
          </select>
        </div>

        <a onClick={() => this.onSave()}>Save</a>
        <div className="avatar-list">
          {this.selectedCharacter().avatarList!.map((val, index) => {
            const avatarClass = this.state.selectedAvatarIndex === index ? 'avatar-list__item--selected' : '';
            return (
              <div key={index} className={`avatar-list__item ${avatarClass}`} onClick={() => this.onAvatarSelect(index)}>
                <img src={val.imageSrc}/>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  render() {

    // user must be logged in to view this page
    if (!this.props.userStore!.user) {
      return <div></div>;
    }

    const { battletag, character_name, character_class, character_guild, character_realm, character_avatar } = this.props.userStore!.user!;
    const { insufficientScope, noCharacters } = this.state;

    return (
      <ScrollToTop>
        <ContentContainer style={{ paddingTop: '40px' }}>
          <div className="flex" style={{ marginBottom: '20px' }}>
            {character_avatar && <Portrait imageSrc={CharacterService.getAvatar(character_avatar!)}/>}
            <div style={{ paddingLeft: '10px' }}>
              {battletag && <div><b>Battletag: </b>{battletag}</div>}
              {character_name && <div><b>Character: </b>{character_name}</div>}
              {character_class && <div><b>Class: </b>{character_class}</div>}
              {character_guild && <div><b>Guild: </b>{character_guild}</div>}
              {character_realm && <div><b>Realm: </b>{character_realm}</div>}
            </div>
            <div className="flex-1" style={{ textAlign: 'right' }}>
              <a onClick={() => this.logout()}>Logout</a>
            </div>
          </div>

          {noCharacters &&
            <div>
              <p>Unable to fetch your characters.</p>
              <a onClick={() => this.setState({ region: 'eu' }, () => this.getCharacters())}>EU account?</a>
            </div>
          }

          <div>
            {insufficientScope === true ? this.renderScopeError() : this.renderDropDowns()}
          </div>

        </ContentContainer>
      </ScrollToTop>
    );
  }
}
