import { customElement, DeesElement, domtools, type TemplateResult, html, property, type CSSResult, state, } from '@design.estate/dees-element';
import { zIndexLayers, zIndexRegistry } from '../00zindex.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-windowlayer': DeesWindowLayer;
  }
}

export interface IOptions_DeesWindowLayer {
  blur: boolean;
}

@customElement('dees-windowlayer')
export class DeesWindowLayer extends DeesElement {
  // STATIC
  public static demo = () => html`<dees-windowlayer></dees-windowlayer>`;

  public static async createAndShow(optionsArg?: IOptions_DeesWindowLayer) {
    const domtoolsInstance = domtools.DomTools.getGlobalDomToolsSync();
    const windowLayer = new DeesWindowLayer();
    windowLayer.options = {
      ...windowLayer.options,
      ...optionsArg,
    }
    document.body.append(windowLayer);
    await domtoolsInstance.convenience.smartdelay.delayFor(0);
    windowLayer.show();
    return windowLayer;
  }

  @state()
  accessor options: IOptions_DeesWindowLayer = {
    blur: false
  };

  @state()
  accessor backdropZIndex: number = 1000;

  @state()
  accessor contentZIndex: number = 1001;

  // INSTANCE
  @property({
    type: Boolean
  })
  accessor visible = false;

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

  public render(): TemplateResult {
    return html`
      ${domtools.elementBasic.styles}
      <style>
        .windowOverlay {
          transition: all 0.2s;
          will-change: transform;
          position: fixed;
          top: 0px;
          left: 0px;
          height: 100vh;
          width: 100vw;
          display: flex;
          justify-content: center;
          align-items: center;
          background: rgba(0, 0, 0, 0.0);
          backdrop-filter: brightness(1) ${this.options.blur ? 'blur(0px)' : ''};
          pointer-events: none;
          z-index: ${this.backdropZIndex};
        }
        .slotContent {
          position: fixed;
          height: 100vh;
          width: 100vw;
          display: flex;
          justify-content: center;
          align-items: center;
          z-index: ${this.contentZIndex};
          pointer-events: none;
        }
        
        .slotContent > * {
          pointer-events: auto;
        }
        
        .visible {
          background: rgba(0, 0, 0, 0.2);
          backdrop-filter: brightness(0.9) ${this.options.blur ? 'blur(2px)' : ''};
          pointer-events: all;
        }
      </style>
      <div @click=${this.dispatchClicked} class="windowOverlay ${this.visible ? 'visible' : null}">
      </div>
      <div class="slotContent">
        <slot></slot>
      </div>
    `;
  }

  firstUpdated() {
    setTimeout(() => {
      this.visible = true;
    }, 100);
  }

  dispatchClicked() {
    this.dispatchEvent(new CustomEvent('clicked'));
  }

  public toggleVisibility () {
    this.visible = !this.visible;
  }
  
  public getContentZIndex(): number {
    return this.contentZIndex;
  }

  public async show() {
    const domtools = await this.domtoolsPromise;
    
    // Get z-indexes from registry
    this.backdropZIndex = zIndexRegistry.getNextZIndex();
    this.contentZIndex = zIndexRegistry.getNextZIndex();
    
    // Register this element
    zIndexRegistry.register(this, this.backdropZIndex);
    
    await domtools.convenience.smartdelay.delayFor(0);
    this.visible = true;
  }

  public async hide() {
    const domtools = await this.domtoolsPromise;
    await domtools.convenience.smartdelay.delayFor(0);
    this.visible = false;
  }

  public async destroy() {
    const domtools = await this.domtoolsPromise;
    await this.hide();
    await domtools.convenience.smartdelay.delayFor(300);
    
    // Unregister from z-index registry
    zIndexRegistry.unregister(this);
    
    this.remove();
  }
}
