import { IdpState } from '../states/idp.state.js';
import * as plugins from '../plugins.js';
import * as elements from '../elements/index.js';

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

@customElement('idp-viewcontainer')
export class IdpViewcontainer extends DeesElement {
  constructor() {
    super();
  }

  public static styles = [
    cssManager.defaultStyles,
    css`
      :host {
        display: block;
        color: #fff;
        font-family: 'Geist Sans';
      }
      :host([hidden]) {
        display: none;
      }
      .viewContainer {
        min-width: 100vh;
        min-height: 100vh;
        background: linear-gradient(-255deg,#06152280 -3.35%,#939eff38 32.79%,#22578480 67.41%,#06152280 97.48%),#212121;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <style></style>
      <div class="viewContainer"></div>
    `;
  }

  public currentElement: plugins.deesElement.DeesElement;
  public async loadElement(viewElement: typeof plugins.deesElement.DeesElement) {
    const idpState = await IdpState.getSingletonInstance();

    // Wait until the viewContainer itself is rendered
    await this.updateComplete;

    // Select the viewContainer
    const viewContainer = this.shadowRoot.querySelector('.viewContainer');

    // Check if viewContainer is present
    if (!viewContainer) {
      throw new Error('View container not found in the rendered DOM.');
    }

    if (!this.currentElement) {
      this.currentElement = viewContainer.children[0] as any;
    }

    // check if current element already is instance of viewElement
    if (this.currentElement instanceof viewElement) {
      return;
    }

    // Remove the current element if it exists
    if (this.currentElement) {
      const currentElement = this.currentElement as any;
      if (currentElement.hide) {
        await currentElement.hide();
      }
      viewContainer.removeChild(this.currentElement);
    }

    // Create a new instance of the viewElement
    const newElement = new viewElement() as any;
    (newElement as any).viewContainer = this;
    viewContainer.appendChild(newElement);

    if (newElement.show) {
      await newElement.show();
    }
    

    // Wait until the new element is fully rendered
    await newElement.updateComplete;

    // Set the new element as the current element
    this.currentElement = newElement;
  }

  public async firstUpdated() {
    const idpState = await IdpState.getSingletonInstance();
    idpState.mainStatePart
      .select((stateArg) => stateArg.view)
      .subscribe(async (viewArg) => {
        switch (viewArg) {
          case 'welcome':
            await this.loadElement(elements.IdpWelcome);
            break;
          case 'login':
            console.log('now on /login');
            await this.loadElement(elements.IdpLoginPrompt);
            break;
          case 'register':
            await this.loadElement(elements.IdpRegistrationPrompt);
            break;
          case 'finishregistration':
            await this.loadElement(elements.IdpRegistrationStepper);
            break;
          case 'account':
            console.log('now on /account');
            await this.loadElement(elements.IdpAccountContent);
            break;
        }
      });
  }
}
