import { Component, JSX, createRef } from "preact";
import { CopyableInputBox } from "../../../elements/CopyableInputBox";
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
import { Form } from "../../../elements/Form";
import { InputWithTitle } from "../../../elements/InputWithTitle";
import { Margin } from "../../../elements/Margin";
import { MarginInline } from "../../../elements/MarginInline";
import { NewTOTPResp } from "../../../../api/types/totp";
import { SecretTitleElement } from "../SecretTitleElement";
import { route } from "preact-router";
import { setErrorText } from "../../../../pageUtils";
import i18next from "i18next";

export class TOTPNewGeneratedForm extends Component<
  { baseMount: string } & DefaultPageProps,
  { exportedData: NewTOTPResp }
> {
  uriInputRef = createRef<HTMLInputElement>();

  render(): JSX.Element {
    if (!this.state.exportedData) {
      return (
        <Form onSubmit={(data) => this.onSubmit(data)}>
          <Margin>
            <InputWithTitle title={i18next.t("common_name")}>
              <input
                class="uk-input uk-form-width-medium"
                name="name"
                type="text"
                placeholder={i18next.t("common_name")}
                required
              />
            </InputWithTitle>
          </Margin>

          <Margin>
            <InputWithTitle title={i18next.t("totp_new_generated_issuer")}>
              <input class="uk-input uk-form-width-medium" name="issuer" type="text" required />
            </InputWithTitle>
          </Margin>

          <Margin>
            <InputWithTitle title={i18next.t("totp_new_generated_account_name")}>
              <input
                class="uk-input uk-form-width-medium"
                name="account_name"
                type="text"
                required
              />
            </InputWithTitle>
          </Margin>

          <Margin>
            <InputWithTitle title={i18next.t("totp_new_generated_algorithm")}>
              <select class="uk-select uk-form-width-medium" name="algorithm">
                {["SHA512", "SHA256", "SHA1"].map((type) => (
                  <option label={type} value={type}>
                    {type}
                  </option>
                ))}
              </select>
            </InputWithTitle>
          </Margin>

          <Margin>
            <InputWithTitle title={i18next.t("totp_new_generated_key_size")}>
              <input
                class="uk-input uk-form-width-medium"
                name="key_size"
                type="number"
                value="20"
              />
            </InputWithTitle>
          </Margin>

          <Margin>
            <InputWithTitle title={i18next.t("totp_new_generated_period")}>
              <input class="uk-input uk-form-width-medium" name="period" type="text" value="30s" />
            </InputWithTitle>
          </Margin>

          <Margin>
            <InputWithTitle title={i18next.t("totp_new_generated_digits")}>
              <input class="uk-input uk-form-width-medium" name="digits" type="number" value="6" />
            </InputWithTitle>
          </Margin>

          <Margin>
            <InputWithTitle title={i18next.t("totp_new_generated_export")}>
              <input class="uk-checkbox" name="exported" type="checkbox" value="yes" checked />
            </InputWithTitle>
          </Margin>

          <p id="errorText" class="uk-text-danger" />

          <MarginInline>
            <button class="uk-button uk-button-primary" type="submit">
              {i18next.t("common_create")}
            </button>
          </MarginInline>
        </Form>
      );
    } else {
      return (
        <>
          <p>{i18next.t("totp_new_generated_warning")}</p>
          <img src={"data:image/png;base64," + this.state.exportedData.barcode} />
          <CopyableInputBox copyable text={this.state.exportedData.url} />
          <button
            class="uk-button uk-button-primary"
            onClick={async () => {
              route("/secrets/totp/list/" + this.props.baseMount);
            }}
          >
            {i18next.t("common_back")}
          </button>
        </>
      );
    }
  }

  async onSubmit(data: FormData): Promise<void> {
    const isExported = data.get("exported") == "yes" ? true : false;

    const parms = {
      generate: true,
      name: data.get("name") as string,
      issuer: data.get("issuer") as string,
      account_name: data.get("account_name") as string,
      exported: isExported,
      key_size: parseInt(data.get("key_size") as string),
      period: data.get("period") as string,
      algorithm: data.get("algorithm") as string,
      digits: parseInt(data.get("digits") as string),
    };

    try {
      const ret = await this.props.api.addNewTOTP(this.props.baseMount, parms);
      if (!isExported) {
        route("/secrets/totp/list/" + this.props.baseMount);
      } else {
        this.setState({ exportedData: ret });
      }
    } catch (e: unknown) {
      const error = e as Error;
      setErrorText(`API Error: ${error.message}`);
    }
  }
}

export class TOTPNewGenerated extends Component<DefaultPageProps> {
  render() {
    const baseMount = this.props.matches["baseMount"];
    return (
      <>
        <SecretTitleElement
          type="totp"
          baseMount={baseMount}
          suffix={i18next.t("totp_new_generated_suffix")}
        />
        <TOTPNewGeneratedForm
          settings={this.props.settings}
          api={this.props.api}
          baseMount={baseMount}
        />
      </>
    );
  }
}