import { LitElement, css, html } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-alert";
import "../../../components/ha-button";
import "../../../components/ha-svg-icon";
import "../../../components/input/ha-input";
import type { HaInput } from "../../../components/input/ha-input";
import {
  cloudLogin,
  cloudRegister,
  cloudResendVerification,
} from "../../../data/cloud";
import type { HomeAssistant } from "../../../types";
import { AssistantSetupStyles } from "../styles";

@customElement("cloud-step-signup")
export class CloudStepSignup extends LitElement {
  @property({ attribute: false }) public hass!: HomeAssistant;

  @state() private _requestInProgress = false;

  @state() private _email?: string;

  @state() private _password?: string;

  @state() private _error?: string;

  @state() private _state?: "VERIFY";

  @query("#email", true) private _emailField!: HaInput;

  @query("#password", true) private _passwordField!: HaInput;

  render() {
    return html`<div class="content">
        <img
          src=${`/static/images/logo_nabu_casa${this.hass.themes?.darkMode ? "_dark" : ""}.png`}
          alt="Nabu Casa logo"
        />
        <h1>
          ${this.hass.localize("ui.panel.config.cloud.register.create_account")}
        </h1>
        ${this._error
          ? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
          : ""}
        ${this._state === "VERIFY"
          ? html`<p>
              ${this.hass.localize(
                "ui.panel.config.cloud.register.confirm_email",
                { email: this._email }
              )}
            </p>`
          : html`<ha-input
                autofocus
                id="email"
                name="email"
                .label=${this.hass.localize(
                  "ui.panel.config.cloud.register.email_address"
                )}
                .disabled=${this._requestInProgress}
                type="email"
                autocomplete="email"
                required
                @keydown=${this._keyDown}
                .validationMessage=${this.hass.localize(
                  "ui.panel.config.cloud.register.email_error_msg"
                )}
              ></ha-input>
              <ha-input
                id="password"
                type="password"
                password-toggle
                name="password"
                .label=${this.hass.localize(
                  "ui.panel.config.cloud.register.password"
                )}
                .disabled=${this._requestInProgress}
                autocomplete="new-password"
                minlength="8"
                required
                @keydown=${this._keyDown}
                .validationMessage=${this.hass.localize(
                  "ui.panel.config.cloud.register.password_error_msg"
                )}
              ></ha-input>`}
      </div>
      <div class="footer side-by-side">
        ${this._state === "VERIFY"
          ? html`<ha-button
                @click=${this._handleResendVerifyEmail}
                .disabled=${this._requestInProgress}
                appearance="plain"
                >${this.hass.localize(
                  "ui.panel.config.cloud.register.resend_confirm_email"
                )}</ha-button
              ><ha-button
                @click=${this._login}
                .disabled=${this._requestInProgress}
                >${this.hass.localize(
                  "ui.panel.config.cloud.register.clicked_confirm"
                )}</ha-button
              >`
          : html`<ha-button
                @click=${this._signIn}
                .disabled=${this._requestInProgress}
                appearance="plain"
                >${this.hass.localize(
                  "ui.panel.config.cloud.login.sign_in"
                )}</ha-button
              >
              <ha-button
                @click=${this._handleRegister}
                .disabled=${this._requestInProgress}
                >${this.hass.localize("ui.common.next")}</ha-button
              >`}
      </div>`;
  }

  private _signIn() {
    fireEvent(this, "cloud-step", { step: "SIGNIN" });
  }

  private _keyDown(ev: KeyboardEvent) {
    if (ev.key === "Enter") {
      this._handleRegister();
    }
  }

  private async _handleRegister() {
    const emailField = this._emailField;
    const passwordField = this._passwordField;

    let invalid = false;

    if (!emailField.reportValidity()) {
      invalid = true;
      emailField.focus();
    }

    if (!passwordField.reportValidity()) {
      if (!invalid) {
        passwordField.focus();
      }
      invalid = true;
    }

    if (invalid) {
      return;
    }

    const email = emailField.value!.toLowerCase();
    const password = passwordField.value!;

    this._requestInProgress = true;

    try {
      await cloudRegister(this.hass, email, password);
      this._email = email;
      this._password = password;
      this._verificationEmailSent();
    } catch (err: any) {
      this._password = "";
      this._error =
        err && err.body && err.body.message
          ? err.body.message
          : "Unknown error";
    } finally {
      this._requestInProgress = false;
    }
  }

  private async _handleResendVerifyEmail() {
    if (!this._email) {
      return;
    }
    try {
      await cloudResendVerification(this.hass, this._email);
      this._verificationEmailSent();
    } catch (err: any) {
      this._error =
        err && err.body && err.body.message
          ? err.body.message
          : "Unknown error";
    }
  }

  private _verificationEmailSent() {
    this._state = "VERIFY";

    setTimeout(() => this._login(), 5000);
  }

  private async _login() {
    if (!this._email || !this._password) {
      return;
    }

    try {
      await cloudLogin({
        hass: this.hass,
        email: this._email,
        password: this._password,
      });
      fireEvent(this, "cloud-step", { step: "DONE" });
    } catch (e: any) {
      if (e?.body?.code === "usernotconfirmed") {
        this._verificationEmailSent();
      } else {
        this._error = "Something went wrong. Please try again.";
      }
    }
  }

  static styles = [
    AssistantSetupStyles,
    css`
      .content {
        width: 100%;
      }
    `,
  ];
}

declare global {
  interface HTMLElementTagNameMap {
    "cloud-step-signup": CloudStepSignup;
  }
}
