import { Button } from "../../../elements/Button";
import { Checkbox } from "../../../elements/forms/Checkbox";
import { Component, createRef } from "preact";
import { CopyableBox } from "../../../elements/CopyableBox";
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
import { ErrorMessage } from "../../../elements/ErrorMessage";
import { FileUploadInput } from "../../../elements/FileUploadInput";
import { Form } from "../../../elements/forms/Form";
import { InputWithTitle } from "../../../elements/InputWithTitle";
import { Margin } from "../../../elements/Margin";
import { SecretTitleElement } from "../SecretTitleElement";
import { TextArea } from "../../../elements/forms/TextArea";
import { fileToBase64 } from "../../../../utils/fileToBase64";
import i18next from "i18next";

export class TransitDecrypt extends Component<DefaultPageProps, { plaintext: string }> {
  errorMessageRef = createRef<ErrorMessage>();

  render() {
    const baseMount = this.props.matches["baseMount"];
    const secretItem = this.props.matches["secretItem"];

    const title = (
      <SecretTitleElement
        type="transit"
        baseMount={baseMount}
        item={secretItem}
        suffix={i18next.t("transit_decrypt_suffix")}
      />
    );

    if (!this.state.plaintext) {
      return (
        <>
          {title}
          <Form onSubmit={async (data) => await this.onSubmit(data)}>
            <Margin>
              <TextArea
                name="ciphertext"
                placeholder={i18next.t("transit_decrypt_input_placeholder")}
              />
            </Margin>

            <Margin>
              <FileUploadInput name="ciphertext_file" />
            </Margin>

            <InputWithTitle title={i18next.t("transit_decrypt_decode_checkbox")}>
              <Checkbox name="decodeBase64Checkbox" />
            </InputWithTitle>

            <Margin>
              <ErrorMessage ref={this.errorMessageRef} />
            </Margin>

            <Button text={i18next.t("transit_decrypt")} color="primary" type="submit" />
          </Form>
        </>
      );
    } else {
      return (
        <>
          {title}
          <CopyableBox
            title={i18next.t("transit_decrypt_decryption_result_title")}
            contentString={this.state.plaintext}
            goBack={() => {
              this.setState({ plaintext: null });
            }}
          />
        </>
      );
    }
  }

  async onSubmit(data: FormData): Promise<void> {
    const baseMount = this.props.matches["baseMount"];
    const secretItem = this.props.matches["secretItem"];

    const decodeBase64 = data.get("decodeBase64Checkbox") as string;

    let ciphertext = data.get("ciphertext") as string;

    const ciphertext_file = data.get("ciphertext_file") as File;
    if (ciphertext_file.size > 0) {
      // TODO: please stop using atob
      ciphertext = atob(
        (await fileToBase64(ciphertext_file)).replace("data:text/plain;base64,", ""),
      );
    }

    try {
      const res = await this.props.api.transitDecrypt(baseMount, secretItem, {
        ciphertext: ciphertext,
      });
      let plaintext = res.plaintext;
      if (decodeBase64 == "on") {
        // Really don't supposed to be doing this...
        plaintext = atob(plaintext);
      }

      this.setState({ plaintext: plaintext });
    } catch (e: unknown) {
      const error = e as Error;
      this.errorMessageRef.current.setErrorMessage(error.message);
    }
  }
}