import React from "react";
import lbry from "../lbry.js";
import lbryio from "../lbryio.js";
import Modal from "./modal.js";
import ModalPage from "./modal-page.js";
import Link from "component/link";
import { RewardLink } from "component/reward-link";
import { FormRow } from "../component/form.js";
import { CreditAmount, Address } from "../component/common.js";
import { getLocal, setLocal } from "../utils.js";
import rewards from "../rewards";

class SubmitEmailStage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      rewardType: null,
      email: "",
      submitting: false,
    };
  }

  handleEmailChanged(event) {
    this.setState({
      email: event.target.value,
    });
  }

  onEmailSaved(email) {
    this.props.setStage("confirm", { email: email });
  }

  handleSubmit(event) {
    event.preventDefault();

    this.setState({
      submitting: true,
    });
    lbryio.call("user_email", "new", { email: this.state.email }, "post").then(
      () => {
        this.onEmailSaved(this.state.email);
      },
      error => {
        if (
          error.xhr &&
          (error.xhr.status == 409 ||
            error.message == __("This email is already in use"))
        ) {
          this.onEmailSaved(this.state.email);
          return;
        } else if (this._emailRow) {
          this._emailRow.showError(error.message);
        }
        this.setState({ submitting: false });
      }
    );
  }

  render() {
    return (
      <section>
        <form
          onSubmit={event => {
            this.handleSubmit(event);
          }}
        >
          <FormRow
            ref={ref => {
              this._emailRow = ref;
            }}
            type="text"
            label={__("Email")}
            placeholder="scrwvwls@lbry.io"
            name="email"
            value={this.state.email}
            onChange={event => {
              this.handleEmailChanged(event);
            }}
          />
          <div className="form-row-submit">
            <Link
              button="primary"
              label={__("Next")}
              disabled={this.state.submitting}
              onClick={event => {
                this.handleSubmit(event);
              }}
            />
          </div>
        </form>
      </section>
    );
  }
}

class ConfirmEmailStage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      rewardType: null,
      code: "",
      submitting: false,
      errorMessage: null,
    };
  }

  handleCodeChanged(event) {
    this.setState({
      code: event.target.value,
    });
  }

  handleSubmit(event) {
    event.preventDefault();
    this.setState({
      submitting: true,
    });

    const onSubmitError = error => {
      if (this._codeRow) {
        this._codeRow.showError(error.message);
      }
      this.setState({ submitting: false });
    };

    lbryio
      .call(
        "user_email",
        "confirm",
        { verification_token: this.state.code, email: this.props.email },
        "post"
      )
      .then(userEmail => {
        if (userEmail.is_verified) {
          this.props.setStage("welcome");
        } else {
          onSubmitError(new Error(__("Your email is still not verified."))); //shouldn't happen?
        }
      }, onSubmitError);
  }

  render() {
    return (
      <section>
        <form
          onSubmit={event => {
            this.handleSubmit(event);
          }}
        >
          <FormRow
            label={__("Verification Code")}
            ref={ref => {
              this._codeRow = ref;
            }}
            type="text"
            name="code"
            placeholder="a94bXXXXXXXXXXXXXX"
            value={this.state.code}
            onChange={event => {
              this.handleCodeChanged(event);
            }}
            helper={__(
              "A verification code is required to access this version."
            )}
          />
          <div className="form-row-submit form-row-submit--with-footer">
            <Link
              button="primary"
              label={__("Verify")}
              disabled={this.state.submitting}
              onClick={event => {
                this.handleSubmit(event);
              }}
            />
          </div>
          <div className="form-field__helper">
            {__("No code?")}
            {" "}
            <Link
              onClick={() => {
                this.props.setStage("nocode");
              }}
              label={__("Click here")}
            />.
          </div>
        </form>
      </section>
    );
  }
}

class WelcomeStage extends React.Component {
  static propTypes = {
    endAuth: React.PropTypes.func,
  };

  constructor(props) {
    super(props);

    this.state = {
      hasReward: false,
      rewardAmount: null,
    };
  }

  onRewardClaim(reward) {
    this.setState({
      hasReward: true,
      rewardAmount: reward.amount,
    });
  }

  render() {
    return !this.state.hasReward
      ? <Modal
          type="custom"
          isOpen={true}
          contentLabel={__("Welcome to LBRY")}
          {...this.props}
        >
          <section>
            <h3 className="modal__header">{__("Welcome to LBRY.")}</h3>
            <p>
              {__(
                "Using LBRY is like dating a centaur. Totally normal up top, and way different underneath."
              )}
            </p>
            <p>{__("Up top, LBRY is similar to popular media sites.")}</p>
            <p>
              {__(
                "Below, LBRY is controlled by users -- you -- via blockchain and decentralization."
              )}
            </p>
            <p>
              {__(
                "Thank you for making content freedom possible! Here's a nickel, kid."
              )}
            </p>
            <div style={{ textAlign: "center", marginBottom: "12px" }}>
              <RewardLink
                type="new_user"
                button="primary"
                onRewardClaim={event => {
                  this.onRewardClaim(event);
                }}
                onRewardFailure={() => this.props.setStage(null)}
                onConfirmed={() => {
                  this.props.setStage(null);
                }}
              />
            </div>
          </section>
        </Modal>
      : <Modal
          type="alert"
          overlayClassName="modal-overlay modal-overlay--clear"
          isOpen={true}
          contentLabel={__("Welcome to LBRY")}
          {...this.props}
          onConfirmed={() => {
            this.props.setStage(null);
          }}
        >
          <section>
            <h3 className="modal__header">{__("About Your Reward")}</h3>
            <p>
              {__("You earned a reward of ")}
              {" "}
              <CreditAmount amount={this.state.rewardAmount} label={false} />
              {" "}{__('LBRY credits, or "LBC".')}
            </p>
            <p>
              {__(
                "This reward will show in your Wallet momentarily, probably while you are reading this message."
              )}
            </p>
            <p>
              {__(
                "LBC is used to compensate creators, to publish, and to have say in how the network works."
              )}
            </p>
            <p>
              {__(
                "No need to understand it all just yet! Try watching or downloading something next."
              )}
            </p>
            <p>
              {__(
                "Finally, know that LBRY is an early beta and that it earns the name."
              )}
            </p>
          </section>
        </Modal>;
  }
}

const ErrorStage = props => {
  return (
    <section>
      <p>{__("An error was encountered that we cannot continue from.")}</p>
      <p>{__("At least we're earning the name beta.")}</p>
      {props.errorText ? <p>{__("Message:")} {props.errorText}</p> : ""}
      <Link
        button="alt"
        label={__("Try Reload")}
        onClick={() => {
          window.location.reload();
        }}
      />
    </section>
  );
};

const PendingStage = props => {
  return (
    <section>
      <p>
        {__("Preparing for first access")} <span className="busy-indicator" />
      </p>
    </section>
  );
};

class CodeRequiredStage extends React.Component {
  constructor(props) {
    super(props);

    this._balanceSubscribeId = null;

    this.state = {
      balance: 0,
      address: getLocal("wallet_address"),
    };
  }

  componentWillMount() {
    this._balanceSubscribeId = lbry.balanceSubscribe(balance => {
      this.setState({
        balance: balance,
      });
    });

    if (!this.state.address) {
      lbry.wallet_unused_address().then(address => {
        setLocal("wallet_address", address);
        this.setState({ address: address });
      });
    }
  }

  componentWillUnmount() {
    if (this._balanceSubscribeId) {
      lbry.balanceUnsubscribe(this._balanceSubscribeId);
    }
  }

  render() {
    const disabled = this.state.balance < 1;
    return (
      <div>
        <section className="section-spaced">
          <p>
            {__(
              "Access to LBRY is restricted as we build and scale the network."
            )}
          </p>
          <p>{__("There are two ways in:")}</p>
          <h3>{__("Own LBRY Credits")}</h3>
          <p>{__("If you own at least 1 LBC, you can get in right now.")}</p>
          <p style={{ textAlign: "center" }}>
            <Link
              onClick={() => {
                setLocal("auth_bypassed", true);
                this.props.setStage(null);
              }}
              disabled={disabled}
              label={__("Let Me In")}
              button={disabled ? "alt" : "primary"}
            />
          </p>
          <p>
            {__("Your balance is ")}<CreditAmount
              amount={this.state.balance}
            />. {__("To increase your balance, send credits to this address:")}
          </p>
          <p>
            <Address
              address={
                this.state.address
                  ? this.state.address
                  : __("Generating Address...")
              }
            />
          </p>
          <p>{__("If you don't understand how to send credits, then...")}</p>
        </section>
        <section>
          <h3>{__("Wait For A Code")}</h3>
          <p>
            {__(
              "If you provide your email, you'll automatically receive a notification when the system is open."
            )}
          </p>
          <p>
            <Link
              onClick={() => {
                this.props.setStage("email");
              }}
              label={__("Return")}
            />
          </p>
        </section>
      </div>
    );
  }
}

export class AuthOverlay extends React.Component {
  constructor(props) {
    super(props);

    this._stages = {
      pending: PendingStage,
      error: ErrorStage,
      nocode: CodeRequiredStage,
      email: SubmitEmailStage,
      confirm: ConfirmEmailStage,
      welcome: WelcomeStage,
    };

    this.state = {
      stage: "pending",
      stageProps: {},
    };
  }

  setStage(stage, stageProps = {}) {
    this.setState({
      stage: stage,
      stageProps: stageProps,
    });
  }

  componentWillMount() {
    lbryio
      .authenticate()
      .then(user => {
        if (!user.has_verified_email) {
          if (getLocal("auth_bypassed")) {
            this.setStage(null);
          } else {
            this.setStage("email", {});
          }
        } else {
          lbryio.call("reward", "list", {}).then(userRewards => {
            userRewards.filter(function(reward) {
              return (
                reward.reward_type == rewards.TYPE_NEW_USER &&
                reward.transaction_id
              );
            }).length
              ? this.setStage(null)
              : this.setStage("welcome");
          });
        }
      })
      .catch(err => {
        this.setStage("error", { errorText: err.message });
        document.dispatchEvent(
          new CustomEvent("unhandledError", {
            detail: {
              message: err.message,
              data: err.stack,
            },
          })
        );
      });
  }

  render() {
    if (!this.state.stage) {
      return null;
    }
    const StageContent = this._stages[this.state.stage];

    if (!StageContent) {
      return (
        <span className="empty">{__("Unknown authentication step.")}</span>
      );
    }

    return this.state.stage != "welcome"
      ? <ModalPage
          className="modal-page--full"
          isOpen={true}
          contentLabel={__("Authentication")}
        >
          <h1>{__("LBRY Early Access")}</h1>
          <StageContent
            {...this.state.stageProps}
            setStage={(stage, stageProps) => {
              this.setStage(stage, stageProps);
            }}
          />
        </ModalPage>
      : <StageContent
          setStage={(stage, stageProps) => {
            this.setStage(stage, stageProps);
          }}
          {...this.state.stageProps}
        />;
  }
}