import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { useStores } from "../../src/store";
import SendIcon from "@material-ui/icons/Send";
import * as aes from "../crypto/aes";
import PIN, { setPinCode } from "../modals/pin";
import * as rsa from "../crypto/rsa";
import { constants } from "../../src/constants";
import CircularProgress from "@material-ui/core/CircularProgress";
import CheckCircleIcon from "@material-ui/icons/CheckCircle";
import actions from "../../src/store/actions";
import {useObserver} from 'mobx-react-lite'

function Onboard(props) {
  const { user, contacts, chats } = useStores();
  const [text, setText] = useState("");
  const [showPin, setShowPin] = useState(false);
  const [checking, setChecking] = useState(false);
  const [alias, setAlias] = useState("");
  const [showAliasInput, setShowAliasInput] = useState(false);

  return useObserver(()=>{

    async function checkCode() {
      if (!text || checking) return;
      setChecking(true);
      try {
        const codeString = atob(text);
        if (codeString.startsWith("keys::")) {
          setShowPin(true);
          return;
        }
        if (codeString.startsWith("ip::")) {
          signupWithIP(codeString);
          return;
        }
      } catch (e) {}

      const r = await user.signupWithCode(text);
      if (!r) {
        setChecking(false);
        return;
      }
      const { ip, password } = r;
      await sleep(200);
      if (ip) {
        const token = await user.generateToken(password || "");
        if (token) setShowAliasInput(true);
      }
      setChecking(false);
    }

    // from relay QR code
    async function signupWithIP(s) {
      const a = s.split("::");
      if (a.length === 1) return;
      setChecking(true);
      const ip = a[1];
      const pwd = a.length > 2 ? a[2] : "";
      await user.signupWithIP(ip);
      await sleep(200);
      const token = await user.generateToken(pwd);
      if (token) {
        setShowAliasInput(true);
      }
      setChecking(false);
    }

    async function aliasEntered(alias) {
      if (checking || !alias) return;
      setChecking(true);
      const publicKey = await rsa.genKeys();
      await contacts.updateContact(user.myid, {
        alias,
        contact_key: publicKey, // set my pubkey in relay
      });
      user.setAlias(alias);
      await Promise.all([
        contacts.addContact({
          alias: user.invite.inviterNickname,
          public_key: user.invite.inviterPubkey,
          status: constants.contact_statuses.confirmed,
          route_hint: user.invite.inviterRouteHint,
        }),
        actions(user.invite.action),
        user.finishInvite(),
        chats.joinDefaultTribe(),
      ]);
      setChecking(false);
      props.onRestore();
    }

    async function pinEntered(pin) {
      try {
        const restoreString = atob(text);
        if (restoreString.startsWith("keys::")) {
          const enc = restoreString.substr(6);
          const dec = await aes.decrypt(enc, pin);
          if (dec) {
            await setPinCode(pin);
            const priv = await user.restore(dec);
            if (priv) {
              rsa.setPrivateKey(priv);
              return props.onRestore();
            }
          }
        }
      } catch (e) {}
      // wrong PIN
      setShowPin(false);
      setChecking(false);
    }

    if (showPin) {
      return (
        <main className="onboard">
          <PIN forceEnterMode onFinish={pinEntered} />
        </main>
      );
    }
    if (showAliasInput && user.invite) {
      const inv = user.invite;
      return (
        <main className="onboard">
          <Logo src="static/sphinx-white-logo.png" />
          <Title>{inv.welcomeMessage}</Title>
          <InputWrap>
            <Input
              value={alias}
              onChange={(e) => setAlias(e.target.value)}
              placeholder="Choose a username"
              style={{ maxWidth: 300 }}
            />
            <CheckCircleIcon
              onClick={() => aliasEntered(alias)}
              style={{
                color: alias ? "#6A8FFF" : "#A5A5A5",
                fontSize: 32,
                position: "absolute",
                right: 14,
                top: 16,
                cursor: "pointer",
              }}
            />
          </InputWrap>
          <div style={{ height: 80 }}>
            {checking && <CircularProgress style={{ color: "white" }} />}
          </div>
        </main>
      );
    }
    return (
      <main className="onboard">
        <Logo src="static/sphinx-white-logo.png" />
        {props.welcome && (
          <>
            <Title>Welcome</Title>
            <Msg data-testid={"onboardtext"}>
              Paste the invitation text or scan the QR code
            </Msg>
            <InputWrap>
              <Input
                id={"onboard-enter-code"}
                value={text}
                onChange={(e) => setText(e.target.value)}
                placeholder="Enter Code..."
              />
              <SendIcon
                id={"onboard-send-button"}
                onClick={checkCode}
                style={{
                  color: text ? "#6A8FFF" : "#A5A5A5",
                  fontSize: 24,
                  position: "absolute",
                  right: 16,
                  top: 20,
                  cursor: "pointer",
                }}
              />
            </InputWrap>
            <div style={{ height: 80 }}>
              {checking && <CircularProgress style={{ color: "white" }} />}
            </div>
          </>
        )}
      </main>
    );
  })
}

const Logo = styled.div`
  background-image: url(${(p) => p.src});
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  width: 120px;
  height: 120px;
  margin-top: 64px;
`;
const Title = styled.h1`
  font-weight: bold;
  color: white;
  margin-top: 64px;
`;
export const Msg = styled.div`
  font-size: 18px;
  max-width: 200px;
  text-align: center;
`;
const InputWrap = styled.div`
  margin-top: 64px;
  margin-bottom: 64px;
  position: relative;
`;
const Input = styled.input`
  width: 500px;
  height: 64px;
  border: none;
  outline: none;
  border-radius: 32px;
  font-size: 16px;
  padding-left: 32px;
  padding-right: 52px;
`;

export default Onboard;

async function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}