import React from 'react';

import { SessionModal } from './SessionModal';
import { SessionButton } from './SessionButton';
import { ToastUtils, UserUtils } from '../../session/utils';
import { DefaultTheme, withTheme } from 'styled-components';
import { PasswordUtil } from '../../util';
import { getPasswordHash } from '../../data/data';
import { QRCode } from 'react-qr-svg';

interface Props {
  onClose: any;
  theme: DefaultTheme;
}

interface State {
  error: string;
  loadingPassword: boolean;
  loadingSeed: boolean;
  recoveryPhrase: string;
  hasPassword: boolean | null;
  passwordHash: string;
  passwordValid: boolean;
}

class SessionSeedModalInner extends React.Component<Props, State> {
  constructor(props: any) {
    super(props);

    this.state = {
      error: '',
      loadingPassword: true,
      loadingSeed: true,
      recoveryPhrase: '',
      hasPassword: null,
      passwordHash: '',
      passwordValid: false,
    };

    this.copyRecoveryPhrase = this.copyRecoveryPhrase.bind(this);
    this.getRecoveryPhrase = this.getRecoveryPhrase.bind(this);
    this.confirmPassword = this.confirmPassword.bind(this);
    this.checkHasPassword = this.checkHasPassword.bind(this);
    this.onEnter = this.onEnter.bind(this);
  }

  public componentDidMount() {
    setTimeout(() => ($('#seed-input-password') as any).focus(), 100);
  }

  public render() {
    const i18n = window.i18n;

    void this.checkHasPassword();
    void this.getRecoveryPhrase();

    const { onClose } = this.props;
    const { hasPassword, passwordValid } = this.state;
    const loading = this.state.loadingPassword || this.state.loadingSeed;

    return (
      <>
        {!loading && (
          <SessionModal
            title={i18n('showRecoveryPhrase')}
            onClose={onClose}
            theme={this.props.theme}
          >
            <div className="spacer-sm" />

            {hasPassword && !passwordValid ? (
              <>{this.renderPasswordView()}</>
            ) : (
              <>{this.renderSeedView()}</>
            )}
          </SessionModal>
        )}
      </>
    );
  }

  private renderPasswordView() {
    const error = this.state.error;
    const i18n = window.i18n;
    const { onClose } = this.props;

    return (
      <>
        <p>{i18n('showRecoveryPhrasePasswordRequest')}</p>
        <input
          type="password"
          id="seed-input-password"
          placeholder={i18n('password')}
          onKeyUp={this.onEnter}
        />

        {error && (
          <>
            <div className="spacer-xs" />
            <div className="session-label danger">{error}</div>
          </>
        )}

        <div className="spacer-lg" />

        <div className="session-modal__button-group">
          <SessionButton text={i18n('ok')} onClick={this.confirmPassword} />

          <SessionButton text={i18n('cancel')} onClick={onClose} />
        </div>
      </>
    );
  }

  private renderSeedView() {
    const i18n = window.i18n;
    const bgColor = '#FFFFFF';
    const fgColor = '#1B1B1B';

    const hexEncodedSeed = window.mnemonic.mn_decode(
      this.state.recoveryPhrase,
      'english'
    );

    return (
      <>
        <div className="session-modal__centered text-center">
          <p className="session-modal__description">
            {i18n('recoveryPhraseSavePromptMain')}
          </p>
          <div className="spacer-xs" />

          <i className="session-modal__text-highlight">
            {this.state.recoveryPhrase}
          </i>
        </div>
        <div className="spacer-lg" />
        <div className="qr-image">
          <QRCode
            value={hexEncodedSeed}
            bgColor={bgColor}
            fgColor={fgColor}
            level="L"
          />
        </div>
        <div className="spacer-lg" />
        <div className="session-modal__button-group">
          <SessionButton
            text={i18n('copy')}
            onClick={() => {
              this.copyRecoveryPhrase(this.state.recoveryPhrase);
            }}
          />
        </div>
      </>
    );
  }

  private confirmPassword() {
    const passwordHash = this.state.passwordHash;
    const passwordValue = jQuery('#seed-input-password').val();
    const isPasswordValid = PasswordUtil.matchesHash(
      passwordValue as string,
      passwordHash
    );

    if (!passwordValue) {
      this.setState({
        error: window.i18n('noGivenPassword'),
      });

      return false;
    }

    if (passwordHash && !isPasswordValid) {
      this.setState({
        error: window.i18n('invalidPassword'),
      });

      return false;
    }

    this.setState({
      passwordValid: true,
      error: '',
    });

    window.removeEventListener('keyup', this.onEnter);

    return true;
  }

  private async checkHasPassword() {
    if (!this.state.loadingPassword) {
      return;
    }

    const hash = await getPasswordHash();
    this.setState({
      hasPassword: !!hash,
      passwordHash: hash || '',
      loadingPassword: false,
    });
  }

  private async getRecoveryPhrase() {
    if (this.state.recoveryPhrase) {
      return false;
    }

    const recoveryPhrase = UserUtils.getCurrentRecoveryPhrase();

    this.setState({
      recoveryPhrase,
      loadingSeed: false,
    });

    return true;
  }

  private copyRecoveryPhrase(recoveryPhrase: string) {
    window.clipboard.writeText(recoveryPhrase);

    ToastUtils.pushCopiedToClipBoard();
    this.props.onClose();
  }

  private onEnter(event: any) {
    if (event.key === 'Enter') {
      this.confirmPassword();
    }
  }
}

export const SessionSeedModal = withTheme(SessionSeedModalInner);