import { IdpState } from '../states/idp.state.js';
import * as plugins from '../plugins.js';
import {
  customElement,
  DeesElement,
  property,
  state,
  html,
  cssManager,
  unsafeCSS,
  css,
  type TemplateResult,
} from '@design.estate/dees-element';

@customElement('idp-registration-stepper')
export class IdpRegistrationStepper extends DeesElement {
  @state()
  accessor usedSubTemplate: TemplateResult;

  @state()
  accessor storedData = {
    validationTokenUrlParam: 'string',
    email: '',
    refreshToken: '',
    jwt: '',
    oneTimeTransferToken: '',
  };

  constructor() {
    super();
  }

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

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

      .main {
        position: absolute;
        top: 0px;
        right: 0px;
        left: 0px;
        bottom: 0px;
        display: flex;
        justify-content: center;
        align-items: center;
        background: var(--background);
      }

      .stepper-container {
        width: 100%;
        max-width: 480px;
        padding: 48px 24px;
      }

      .error-message {
        text-align: center;
        color: var(--muted-foreground);
        font-size: 14px;
        line-height: 1.6;
        padding: 24px;
      }

      dees-stepper {
        --dees-stepper-background: transparent;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <div class="main">
        <div class="stepper-container">
          ${this.usedSubTemplate
            ? this.usedSubTemplate
            : html`<dees-spinner size="60"></dees-spinner>`}
        </div>
      </div>
    `;
  }

  public async firstUpdated() {
    const idpState = await IdpState.getSingletonInstance();
    await this.domtoolsPromise;
    const parsedUrl = plugins.smarturl.Smarturl.createFromUrl(window.location.href);
    this.storedData.validationTokenUrlParam = parsedUrl.searchParams['validationtoken'];
    console.log(`validationToken is ${this.storedData.validationTokenUrlParam}`);
    if (!this.storedData.validationTokenUrlParam) {
      this.usedSubTemplate = html`
        <div class="error-message">
          You need a validation token, but we couldn't find one.<br/>
          Please contact support for assistance.
        </div>
      `;
      await this.domtools.convenience.smartdelay.delayFor(5000);
      window.location.href = '/';
      return;
    }
    // lets verify the info;
    let tokenErrorMessage: string;
    const resAfterRegEmailClicked = await idpState.idpClient.requests.afterRegistrationEmailClicked
      .fire({
        token: this.storedData.validationTokenUrlParam,
      })
      .catch(
        (
          err: (typeof DeesElement)['prototype']['domtools']['convenience']['typedrequest']['TypedResponseError']['prototype']
        ) => {
          tokenErrorMessage = err.errorText;
          return;
        }
      );

    console.log(resAfterRegEmailClicked);

    if (!resAfterRegEmailClicked || !resAfterRegEmailClicked.email) {
      this.usedSubTemplate = html`
        <div class="error-message">
          The supplied validation token does not match any registration sessions.<br/>
          ${tokenErrorMessage ? html`<br/>Reason: ${tokenErrorMessage}` : null}
        </div>
      `;
      await this.domtools.convenience.smartdelay.delayFor(5000);
      idpState.domtools.router.pushUrl('/');
      return;
    } else {
      this.storedData.email = resAfterRegEmailClicked.email;
    }

    // lets continue with UI
    this.usedSubTemplate = html`<dees-stepper
      .steps=${[
        {
          title: 'What is your name?',
          content: html`
            <dees-form>
              <dees-input-text
                key="email"
                label="Your Email"
                value="${this.storedData.email}"
                disabled
              ></dees-input-text>
              <dees-input-text key="firstName" required label="First Name"></dees-input-text>
              <dees-input-text key="lastName" required label="Last Name"></dees-input-text>
              <dees-form-submit>Next</dees-form-submit>
            </dees-form>
          `,
          validationFunc: async (stepperArg, elementArg) => {
            const deesForm: plugins.deesCatalog.DeesForm = elementArg.querySelector('dees-form');
            deesForm.addEventListener('formData', async (eventArg: CustomEvent) => {
              const response = await idpState.idpClient.requests.setData
                .fire({
                  token: this.storedData.validationTokenUrlParam,
                  userData: {
                    name: `${eventArg.detail.data.firstName} ${eventArg.detail.data.lastName}`,
                    connectedOrgs: null,
                    email: null,
                    status: null,
                    username: null,
                  },
                })
                .catch(
                  (
                    errArg: (typeof DeesElement)['prototype']['domtools']['convenience']['typedrequest']['TypedResponseError']['prototype']
                  ) => {
                    deesForm.setStatus('error', errArg.errorText);
                  }
                );
              deesForm.setStatus('success', 'ok!');
              stepperArg.goNext();
            });
          },
          onReturnToStepFunc: async (stepperArg, stepElementArg) => {
            const deesForm = stepElementArg.querySelector('dees-form');
            deesForm.setStatus('normal', 'Edit and Next');
          },
        },
        {
          title: 'What is your mobile number?',
          content: html`
            <dees-form>
              <dees-input-text
                key="mobileNumber"
                required
                label="Your Mobile Number"
              ></dees-input-text>
              <dees-form-submit>Next</dees-form-submit>
            </dees-form>
          `,
          validationFunc: async (stepperArg, elementArg) => {
            const deesForm: plugins.deesCatalog.DeesForm = elementArg.querySelector('dees-form');
            deesForm.addEventListener('formData', async (eventArg: CustomEvent) => {
              const response = await idpState.idpClient.requests.mobileNumberVerification
                .fire({
                  token: this.storedData.validationTokenUrlParam,
                  mobileNumber: eventArg.detail.data.mobileNumber,
                })
                .catch(
                  (
                    errArg: (typeof DeesElement)['prototype']['domtools']['convenience']['typedrequest']['TypedResponseError']['prototype']
                  ) => {
                    deesForm.setStatus('error', errArg.errorText);
                  }
                );
              deesForm.setStatus('success', 'ok!');
              stepperArg.goNext();
            });
          },
          onReturnToStepFunc: async (stepperArg, stepElementArg) => {
            const deesForm = stepElementArg.querySelector('dees-form');
            deesForm.setStatus('normal', 'Edit and Next');
          },
        },
        {
          title: 'What is the Verification Code?',
          content: html`
            <dees-form>
              <dees-input-text
                key="verificationCode"
                required
                label="Verification Code"
              ></dees-input-text>
              <dees-form-submit>Next</dees-form-submit>
            </dees-form>
          `,
          validationFunc: async (stepperArg, elementArg) => {
            const deesForm: plugins.deesCatalog.DeesForm = elementArg.querySelector('dees-form');
            deesForm.addEventListener('formData', async (eventArg: CustomEvent) => {
              const response = await idpState.idpClient.requests.mobileNumberVerification.fire({
                token: this.storedData.validationTokenUrlParam,
                verificationCode: eventArg.detail.data.verificationCode,
              });

              if (response.verficationCodeOk) {
                deesForm.setStatus('success', 'ok!');
                stepperArg.goNext();
              } else {
                deesForm.setStatus('error', 'wrong code!');
                await this.domtools.convenience.smartdelay.delayFor(3000);
                deesForm.setStatus('normal', 'Retry And Next!');
              }
            });
          },
          onReturnToStepFunc: async (stepperArg, stepElementArg) => {
            stepperArg.goBack();
            const deesForm = stepElementArg.querySelector('dees-form');
            deesForm.setStatus('normal', 'Next');
          },
        },
        {
          title: 'Create a secure password:',
          content: html`
            <dees-form>
              <dees-input-text
                key="password"
                required
                label="Your New Secure Password"
              ></dees-input-text>
              <dees-form-submit>Next</dees-form-submit>
            </dees-form>
          `,
          validationFunc: async (stepperArg, elementArg) => {
            const deesForm: plugins.deesCatalog.DeesForm = elementArg.querySelector('dees-form');
            deesForm.addEventListener('formData', async (eventArg: CustomEvent) => {
              const response = await idpState.idpClient.requests.setData.fire({
                token: this.storedData.validationTokenUrlParam,
                userData: {
                  username: null,
                  email: null,
                  name: null,
                  connectedOrgs: null,
                  status: null,
                  password: eventArg.detail.data.password,
                },
              });
              const finishRegistrationResponse =
                await idpState.idpClient.requests.finishRegistration.fire({
                  token: this.storedData.validationTokenUrlParam,
                });
              deesForm.setStatus('pending', 'User created!');
              await this.domtools.convenience.smartdelay.delayFor(500);
              deesForm.setStatus('pending', 'Obtaining Refresh Token...');
              const loginResponse =
                await idpState.idpClient.requests.loginWithUserNameAndPassword.fire({
                  username: this.storedData.email,
                  password: eventArg.detail.data.password,
                });
              this.storedData.refreshToken = loginResponse.refreshToken;

              deesForm.setStatus('pending', 'Obtaining JWT...');
              const jwtResponse = await idpState.idpClient.requests.obtainJwt.fire({
                refreshToken: this.storedData.refreshToken,
              });

              deesForm.setStatus('success', 'Ok! Lets Go!');
              await idpState.idpClient.setJwt(jwtResponse.jwt);
              idpState.domtools.router.pushUrl('/account');
            });
          },
        },
      ] as plugins.deesCatalog.IStep[]}
    ></dees-stepper>`;
    await this.domtools.convenience.smartdelay.delayFor(100);
  }
}
