import * as plugins from '../plugins.js';

import {
  customElement,
  DeesElement,
  property,
  html,
  type TemplateResult,
  css,
  cssManager,
  state,
  domtools,
} from '@design.estate/dees-element';

// third party catalogs
import '@uptime.link/webwidget';

import '@design.estate/dees-catalog';
import { DeesForm, DeesFormSubmit, DeesInputText } from '@design.estate/dees-catalog';
import { IdpState } from '../states/idp.state.js';

declare global {
  interface HTMLElementTagNameMap {
    'idp-loginprompt': IdpLoginPrompt;
  }
}

@customElement('idp-loginprompt')
export class IdpLoginPrompt extends DeesElement {
  public static demo = () => html`<idp-loginprompt></idp-loginprompt>`;

  @property()
  accessor productOfInterest: string;

  @property()
  accessor jwt: string;

  @property({
    reflect: true,
    type: Object,
  })
  accessor appData: plugins.idpInterfaces.data.IApp;

  public jwtObserable = new domtools.plugins.smartrx.rxjs.Subject<string>();

  constructor() {
    super();
    domtools.elementBasic.setup();
  }

  public static styles = [
    cssManager.defaultStyles,
    css`
      :host {
        --foreground: hsl(0 0% 98%);
        --muted-foreground: hsl(240 5% 64.9%);

        font-family: 'Geist Sans', -apple-system, BlinkMacSystemFont, sans-serif;
        display: block;
        color: var(--foreground);
      }

      .form-header {
        margin-bottom: 32px;
        text-align: center;
      }

      .form-header h2 {
        font-size: 24px;
        font-weight: 600;
        color: var(--foreground);
        margin: 0 0 8px 0;
        letter-spacing: -0.02em;
      }

      .form-header p {
        font-size: 14px;
        color: var(--muted-foreground);
        margin: 0;
      }

      dees-form {
        display: flex;
        flex-direction: column;
        gap: 16px;
      }

      .form-footer {
        margin-top: 24px;
        text-align: center;
        font-size: 14px;
        color: var(--muted-foreground);
      }

      .form-footer a {
        color: var(--foreground);
        text-decoration: none;
        font-weight: 500;
        cursor: pointer;
        transition: opacity 0.15s ease;
      }

      .form-footer a:hover {
        opacity: 0.8;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <idp-centercontainer>
        <div class="form-header">
          <h2>Sign in to your account</h2>
          <p>Enter your credentials to continue</p>
        </div>
        <dees-form
          id="loginForm"
          @formData="${(eventArg) => {
            this.login({
              emailAddress: eventArg.detail.data.emailAddress,
              passwordArg: eventArg.detail.data.password,
            });
          }}"
        >
          <dees-input-text
            id="loginEmailInput"
            .required=${true}
            key="emailAddress"
            label="Email or Username"
          ></dees-input-text>
          <dees-input-text
            .id=${'loginPasswordInput'}
            .key=${'password'}
            .label=${'Password'}
            .isPasswordBool=${true}
          ></dees-input-text>
          <dees-form-submit id="loginSubmitButton"></dees-form-submit>
        </dees-form>
        <div class="form-footer">
          Don't have an account? <a @click=${async () => {
            const idpState = await IdpState.getSingletonInstance();
            idpState.domtools.router.pushUrl('/register');
          }}>Create one</a>
        </div>
      </idp-centercontainer>
    `;
  }

  public async firstUpdated() {
    const domtoolsInstance = await this.domtoolsPromise;
    const loginForm: DeesForm = this.shadowRoot.querySelector('#loginForm');
    const loginPasswordInput: DeesInputText = loginForm.querySelector('#loginPasswordInput');
    const loginSubmitButton: DeesFormSubmit = loginForm.querySelector('#loginSubmitButton');
    const setButtonText = async () => {
      if (loginPasswordInput.value) {
        console.log('updating text of loginprompt.');
        loginSubmitButton.text = 'Login';
      } else {
        loginSubmitButton.text = 'Send magic link (or enter password)';
      }
    };
    loginForm.changeSubject.subscribe(() => {
      console.log(`checking button text ${loginPasswordInput.value}`);
      setButtonText();
    });
    setButtonText();
  }

  private login = async (valueArg: { emailAddress: string; passwordArg: string }) => {
    // lets disable the register button
    const registerButton: plugins.deesCatalog.DeesButton = this.shadowRoot.querySelector('.registerButton');
    registerButton.disabled = true;
    // lets define the needed requests
    const idpState = await IdpState.getSingletonInstance();
    const loginForm: DeesForm = this.shadowRoot.querySelector('#loginForm');
    const loginRequestWithUsernameAndPassword =
      new domtools.TypedRequest<plugins.idpInterfaces.request.IReq_LoginWithEmailOrUsernameAndPassword>(
        '/typedrequest',
        'loginWithEmailOrUsernameAndPassword'
      );
    const loginRequestWithEmail =
      new domtools.TypedRequest<plugins.idpInterfaces.request.IReq_LoginWithEmail>(
        '/typedrequest',
        'loginWithEmail'
      );

    // lets do the actual logging in
    if (valueArg.emailAddress && valueArg.passwordArg) {
      loginForm.setStatus('pending', 'logging in...');
      const response = await loginRequestWithUsernameAndPassword
        .fire({
          username: valueArg.emailAddress, // TODO: rename to emailAddress
          password: valueArg.passwordArg,
        })
        .catch(() => {
          loginForm.setStatus('error', 'could not log you in. Try Again!');
          return;
        });
      if (!response) {
        return;
      }
      if (response.refreshToken) {
        loginForm.setStatus('pending', 'obtained refreshToken...');
        const jwt = await idpState.idpClient.refreshJwt(response.refreshToken);
        if (jwt) {
          loginForm.setStatus('success', 'obtained jwt.');
          idpState.domtools.router.pushUrl('/account');
        } else {
          loginForm.setStatus('error', 'something went wrong');
        }
      } else {
      }
    } else if (valueArg.emailAddress && !valueArg.passwordArg) {
      loginForm.setStatus('pending', 'sending magic link...');
      const response = await loginRequestWithEmail.fire({
        email: valueArg.emailAddress,
      });
      if (response.status === 'ok') {
        loginForm.setStatus('success', 'Please check your email!');
      }
      console.log(response);
    }
  };

  public async dispatchJwt(jwtArg?: string) {
    if (jwtArg !== undefined) {
      console.log(`dispatching jwt from loginprompt.`);
      this.jwt = jwtArg;
      await domtools.plugins.smartdelay.delayFor(200);
      this.dispatchEvent(
        new CustomEvent('leleLoginGotJwt', {
          detail: {
            jwt: this.jwt,
          },
        })
      );
      this.jwtObserable.next(this.jwt);
    }
  }

  public async focus() {
    (
      this.shadowRoot.querySelector('#loginEmailInput') as plugins.deesCatalog.DeesInputText
    ).focus();
  }

  public async show() {
    await this.updateComplete;
    const centerContainer = this.shadowRoot.querySelector('idp-centercontainer');
    await centerContainer.show();
  }

  public async hide() {
    await this.updateComplete;
    const centerContainer = this.shadowRoot.querySelector('idp-centercontainer');
    await centerContainer.hide();
  }
}
