import React from "react";
import { Row, Col, Container, Form, Image } from "react-bootstrap";
import { create_wallet_util } from "../../utils/wallet_creation";

import WalletHome from "../wallet/home";
import { open_twm_file, save_twm_file } from "../../utils/twm_actions";
import ProgressIcon from "../customComponents/ProgressIcon";

import Loader from "react-loader-spinner";

import { AiOutlineInfoCircle } from "react-icons/ai";
import { IoIosArrowBack } from "react-icons/io";
import { IconContext } from "react-icons";
import ReactTooltip from "react-tooltip";

const crypto = window.require("crypto");

let { dialog } = window.require("electron").remote;

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

    this.state = {
      daemon_host: "",
      daemon_port: 0,
      new_path: "",
      password: "",
      safex_key: null,
      success: false,
      network: "stagenet",
      testnet: false,
      wallet: null,
      wallet_made: false,
      loading: false,
      pageNumber: 1,
      showKeys: false
    };
    this.wallet_meta = null;
  }

  async componentDidMount() {}

  handleInitialKeysClose = () => {
    this.setState({showKeys: false});
  }

  set_path = (e) => {
    e.preventDefault();

    let sails_path = dialog.showSaveDialogSync();
    let new_path = sails_path;

    try {
      if (new_path.length > 0) {
        this.setState({ new_path: new_path });
      }
    } catch (err) {
      console.log("Error! No path set.");
    }
  };

  change_path = (e) => {
    e.preventDefault();
    this.setState({ new_path: "" });
  };

  set_daemon_state = (e) => {
    e.preventDefault();
    this.setState({
      daemon_host: e.target.daemon_host.value,
      daemon_port: parseInt(e.target.daemon_port.value),
    });
  };

  change_daemon = (e) => {
    e.preventDefault();
    alert("hey");
    this.setState({ daemon_host: "", daemon_port: 0 });
  };

  set_password = (e) => {
    e.preventDefault();
    if (e.target.password.value === e.target.repeat_password.value) {
      this.setState({ password: e.target.password.value, pageNumber: 4 });
    } else {
      alert("Your passwords dont match! Please try again.");
    }
  };

  change_password = (e) => {
    e.preventDefault();
    this.setState({ password: "" });
  };

  make_wallet_result = async (error, wallet) => {
    if (error) {
      this.setState({ loading: false });
    } else {
      try {
        console.log(wallet);
        wallet.setSeedLanguage("English");
        try {
          let twm_obj = {};

          twm_obj.version = 1;
          twm_obj.api = {};
          twm_obj.api.urls = {};
          /*twm_obj.api.urls.theworldmarketplace = {};
                    twm_obj.api.urls.theworldmarketplace.url = 'api.theworldmarketplace.com';*/
          twm_obj.accounts = {};
          twm_obj.settings = {};

          //for each account make one, and within an account you have urls and keys  the top lvel api urls is for top level non account actions
          var accs = wallet.getSafexAccounts();
          for (const acc of accs) {
            console.log(acc);
            twm_obj.accounts[acc.username] = {};
            twm_obj.accounts[acc.username].username = acc.username;
            twm_obj.accounts[acc.username].data = acc.data;
            twm_obj.accounts[acc.username].safex_public_key = acc.publicKey;
            twm_obj.accounts[acc.username].safex_private_key = acc.privateKey;
            twm_obj.accounts[acc.username].urls = {};
            /*
                                                twm_obj.accounts[acc.username].urls.theworldmarketplace = {};
                                                twm_obj.accounts[acc.username].urls.theworldmarketplace.url = 'api.theworldmarketplace.com';
                        */
          }

          const algorithm = "aes-256-ctr";
          const cipher = crypto.createCipher(algorithm, this.state.password);
          let crypted = cipher.update(JSON.stringify(twm_obj), "utf8", "hex");
          crypted += cipher.final("hex");

          const hash1 = crypto.createHash("sha256");
          hash1.update(JSON.stringify(twm_obj));
          console.log(`password ${this.state.password}`);
          console.log(JSON.stringify(twm_obj));

          let twm_save = await save_twm_file(
            this.state.new_path + ".twm",
            crypted,
            this.state.password,
            hash1.digest("hex")
          );

          try {
            let twm_file = await open_twm_file(
              this.state.new_path + ".twm",
              this.state.password
            );
            console.log(twm_file);

            localStorage.setItem("twm_file", JSON.stringify(twm_file.contents));
          } catch (err) {
            this.setState({ loading: false });
            console.error(err);
            console.error(`error opening twm file after save to verify`);
          }
          console.log(twm_save);
        } catch (err) {
          this.setState({ loading: false });
          console.error(err);
          console.error(`error at initial save of the twm file`);
        }
        this.setState({ wallet_made: true, wallet: wallet, loading: false, showKeys: true });
      } catch (err) {
        this.setState({ loading: false });
        console.error(err);
        console.error(`error at open_wallet_result`);
      }
    }
  };

  make_wallet = async (e) => {
    e.preventDefault();
    this.setState({ loading: true });
    try {
      let daemon_string = `${this.state.daemon_host}:${this.state.daemon_port}`;
      create_wallet_util(
        this.state.new_path,
        this.state.password,
        0,
        this.state.network,
        daemon_string,
        this.make_wallet_result
      );
    } catch (err) {
      this.setState({ loading: false });
      console.error(err);
      console.error("error on initial recovery");
    }
  };

  backToSelect = () => {
    this.props.history.push({ pathname: "/select_entry" });
  };

  goBack = (e) => {
    e.preventDefault();
    if (this.state.pageNumber > 1) {
        return this.setState({pageNumber: this.state.pageNumber - 1});
    } 

    this.backToSelect();
  };

  get isLoading() {
      return this.state.loading === true;
  }

  renderUrlTooltip() {
    return (
    <>
    <AiOutlineInfoCircle size={15} className="ml-2" data-tip data-for="daemonHostInfo" />
    <ReactTooltip
      id="daemonHostInfo"
      type="info"
      effect="solid"
      place="bottom"
    >
      <span>
        This is the URL used to connect to the Safex
        blockchain.
        <br />
        You can use the default provided by the Safex
        Foundation
        <br />
        or replace it with your own full node.
        <br />
        <br />
        <ul className="mb-4">
          <li>
            The default self hosted wallet setup would be:
          </li>
          <li className="mt-4">
            HOST: <b>127.0.0.1</b>
          </li>
          <li className="mt-1">
            PORT: <b>17402</b>
          </li>
          <li className="mt-2">
            The default is rpc.safex.org:30393
          </li>
        </ul>
      </span>
    </ReactTooltip>
    </>)
  }

  render() {
      if (this.isLoading) {
        return (
        <Container fluid className="h-100">
            <Container
            fluid
            className="height100 d-flex flex-column justify-content-center align-items-center"
          >
         <Loader type="ThreeDots" color="#13D3FD" height={40} width={80} />
         </Container>
        </Container>)
      }

      if (this.state.wallet_made) {
        return (<div className={`w-100 h-100`}>
          <div className="w-100 h-100">
          <WalletHome
            wallet={this.state.wallet}
            daemon_host={this.state.daemon_host}
            daemon_port={this.state.daemon_port}
            password={this.state.password}
            wallet_path={this.state.new_path}
            showKeys={this.state.showKeys}
            onInitialShowClose={this.handleInitialKeysClose} />      
          </div>
        </div>)
      }

    return (
      <div
        fluid
        className={`w-100 h-100`}
      >
          <div
            fluid
            className="w-100 h-100 d-flex flex-column justify-content-center align-items-center"
          >
            <div className="start-background-image h-100 w-100 d-flex flex-column justify-content-center align-items-center">
              <Image
                className="entry-mini-logo"
                src={require("./../../img/safex-multi-small.svg")}
              />
              <Image
                onClick={() => {
                  alert("Closing Wallet... (TEST)");
                }}
                className="entry-off-button pointer"
                src={require("./../../img/off_black.svg")}
              />

              <Row className="entry-progress-row">
                <Col
                  onClick={this.goBack}
                  className="d-flex align-items-center entry-back-text pointer"
                  md={2}
                >
                  <IconContext.Provider
                    value={{ color: "#13D3FD", size: "3rem" }}
                  >
                    <IoIosArrowBack />
                  </IconContext.Provider>
                  BACK
                </Col>

                <a
                  onClick={() => {
                    this.setState({ pageNumber: 1 });
                  }}
                >
                  <ProgressIcon
                    number={1}
                    color={
                      this.state.pageNumber === 1
                        ? "progress-icon-color"
                        : this.state.new_path.length > 0
                        ? "progress-icon-color-complete"
                        : ""
                    }
                    title={"SAVE FILES"}
                  />
                </a>

                <a
                  onClick={() => {
                    this.setState({ pageNumber: 2 });
                  }}
                >
                  <ProgressIcon
                    number={2}
                    title={"NETWORK CONNECTION"}
                    color={
                      this.state.pageNumber === 2
                        ? "progress-icon-color"
                        : this.state.daemon_host.length > 0
                        ? "progress-icon-color-complete"
                        : ""
                    }
                  />
                </a>

                <a
                  onClick={() => {
                    this.setState({ pageNumber: 3 });
                  }}
                >
                  <ProgressIcon
                    number={3}
                    title={"YOUR PASSWORD"}
                    color={
                      this.state.pageNumber === 3
                        ? "progress-icon-color"
                        : this.state.password.length > 0
                        ? "progress-icon-color-complete"
                        : ""
                    }
                  />
                </a>
              </Row>

              {this.state.pageNumber === 1 && (
                <div>
                  {this.state.new_path.length > 0 ? (
                    <div className="entry-container">
                        <p className="h3">
                          {" "}
                          This file will be saved to:{" "}
                          <br /> <i>{this.state.new_path}</i>
                        </p>

                        <button
                          className="mx-auto custom-button-entry"
                          onClick={this.change_path}
                        >
                          Change Path
                        </button>

                        <button
                          className="mt-2 mx-auto custom-button-entry orange-border"
                          onClick={() => this.setState({ pageNumber: 2 })}
                        >
                          Continue
                        </button>
                    </div>
                  ) : (
                    <div className="entry-container">
                      <p className="h3">
                        Where would you like to save your Safex Wallet Files?
                      </p>
                      <Form
                        className="mt-2 mb-2"
                        id="set_path"
                        onSubmit={this.set_path}
                      >
                        <input className="display-none" type="file" />
                          <button
                            className="mx-auto custom-button-entry orange-border mt-2"
                            type="submit"
                            variant="primary"
                          >
                            Select File Path
                          </button>
                      </Form>
                    </div>
                  )}
                </div>
              )}

              {this.state.new_path.length > 0 && this.state.pageNumber === 2 && (
                <div className="entry-container">
                  {this.state.daemon_host.length < 1 ? (
                    <form
                      id="set_daemon"
                      onSubmit={this.set_daemon_state}
                      className=""
                    >
                      <label className="entry-form-label" htmlFor="daemon-host">
                        Daemon Host:
                        {this.renderUrlTooltip()}
                      </label>

                      <input
                        id="daemon-host"
                        className="my-2 entry-form-input"
                        name="daemon_host"
                        defaultValue="stagenetrpc.safex.org"
                        placedholder="set the ip address of the safex blockchain"
                      />

                      <label htmlFor="daemon-port">Daemon Port:</label>

                      <input
                        id="daemon-port"
                        className="mt-2 mb-3"
                        name="daemon_port"
                        defaultValue="30393"
                        placedholder="set the port of the safex blockchain"
                      />

                      <button
                        className="w-100 custom-button-entry orange-border"
                        type="submit"
                        variant="primary"
                      >
                        Set Connection
                      </button>
                    </form>
                  ) : (
                    <div className="d-flex flex-column justify-content-around h-100">
                      <p className="h3">
                        You will be connected to:
                        <br />
                        <i>
                          {this.state.daemon_host}:{this.state.daemon_port}
                        </i>
                      </p>

                      <button
                        className="w-100 mt-3 custom-button-entry"
                        type="button"
                        onClick={() =>
                          this.setState({ daemon_host: "", daemon_port: 0 })
                        }
                      >
                        Reset Connection
                      </button>

                      <button
                        className="w-100 mt-2 mx-auto custom-button-entry orange-border"
                        onClick={() => this.setState({ pageNumber: 3 })}
                      >
                        Continue
                      </button>
                    </div>
                  )}
                </div>
              )}

              {this.state.pageNumber === 3 && (
                <div className="entry-container">
                  <form
                    id="set_password"
                    className=""
                    onSubmit={this.set_password}
                  >
                    <label htmlFor="password-input">Choose a password</label>

                    <input
                      id="password-input"
                      type="password"
                      name="password"
                      className="mt-2 mb-2"
                    />

                    <label htmlFor="repeat-password-input">
                      Confirm your password
                    </label>

                    <input
                      id="repeat-password-input"
                      name="repeat_password"
                      className="mt-2 mb-2"
                      type="password"
                    />

                    <button
                      type="submit"
                      className="w-100 custom-button-entry orange-border mt-3"
                    >
                      Set Password
                    </button>
                  </form>
                </div>
              )}

              {this.state.new_path.length > 0 &&
              this.state.daemon_host.length > 0 &&
              this.state.wallet_made === false &&
              this.state.password.length > 0 &&
              this.state.pageNumber === 4 && (
                <div className="entry-container">
                  <p className="h3">
                    This file will be saved to: <br /> <i>{this.state.new_path}</i>
                  </p>

                  <button
                    autoFocus
                    onClick={this.make_wallet}
                    className="mt-2 mx-auto custom-button-entry orange-border"
                  >
                    Create New Wallet
                  </button>
                </div>
              )}
            </div>
          </div>
      </div>
    );
  }
}