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

import { demoFunc } from './dees-modal.demo.js';
import {
  customElement,
  html,
  DeesElement,
  property,
  type TemplateResult,
  cssManager,
  css,
  type CSSResult,
  unsafeCSS,
  unsafeHTML,
  state,
} from '@design.estate/dees-element';

import * as domtools from '@design.estate/dees-domtools';
import { DeesWindowLayer } from './dees-windowlayer.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-modal': DeesModal;
  }
}

@customElement('dees-modal')
export class DeesModal extends DeesElement {
  // STATIC
  public static demo = demoFunc;

  public static async createAndShow(optionsArg: {
    heading: string;
    content: TemplateResult;
    menuOptions: plugins.tsclass.website.IMenuItem<DeesModal>[];
  }) {
    const body = document.body;
    const modal = new DeesModal();
    modal.heading = optionsArg.heading;
    modal.content = optionsArg.content;
    modal.menuOptions = optionsArg.menuOptions;
    modal.windowLayer = await DeesWindowLayer.createAndShow({
      blur: true,
    });
    modal.windowLayer.addEventListener('click', async () => {
      await modal.destroy();
    });
    body.append(modal.windowLayer);
    body.append(modal);
  }

  // INSTANCE

  @property({
    type: String,
  })
  public heading = '';

  @state({})
  public content: TemplateResult;

  @state({})
  public menuOptions: plugins.tsclass.website.IMenuItem<DeesModal>[] = [];

  constructor() {
    super();
  }

  public static styles = [
    cssManager.defaultStyles,
    css`
      :host {
        font-family: 'Geist Sans', sans-serif;
        color: ${cssManager.bdTheme('#333', '#fff')};
        will-change: transform;
      }
      .modalContainer {
        display: flex;
        position: fixed;
        top: 0px;
        left: 0px;
        width: 100vw;
        height: 100vh;
        box-sizing: border-box;
        align-items: center;
        justify-content: center;
        z-index: 2000;
      }
      .modal {
        will-change: transform;
        transform: translateY(0px) scale(0.95);
        opacity: 0;
        width: 480px;
        min-height: 120px;
        background: #111;
        border-radius: 8px;
        border: 1px solid #222;
        transition: all 0.2s;
        overflow: hidden;
        box-shadow: 0px 2px 5px #00000080;
      }

      .modal.show {
        opacity: 1;
        transform: translateY(0px) scale(1);
      }

      .modal.show.predestroy {
        opacity: 0;
        transform: translateY(10px) scale(1);
      }

      .modal .heading {
        height: 32px;
        font-family: 'Geist Sans', sans-serif;
        line-height: 32px;
        text-align: center;
        font-weight: 600;
        font-size: 12px;
        border-bottom: 1px solid #222;
      }

      .modal .content {
        padding: 16px;
      }
      .modal .bottomButtons {
        display: flex;
        flex-direction: row;
        border-top: 1px solid #222;
        justify-content: flex-end;
      }

      .modal .bottomButtons .bottomButton {
        margin: 8px 0px;
        padding: 8px 12px;
        border-radius: 4px;
        line-height: 16px;
        text-align: center;
        font-size: 14px;
        cursor: default;
        user-select: none;
      }

      .modal .bottomButtons .bottomButton:first-child {
        margin-left: 8px;
      }
      .modal .bottomButtons .bottomButton:last-child {
        margin-right: 8px;
      }

      .modal .bottomButtons .bottomButton:hover {
        background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
      }
      .modal .bottomButtons .bottomButton:active {
        background: ${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)};
      }
      .modal .bottomButtons .bottomButton:last-child {
        border-right: none;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <style>
        .modal .bottomButtons {
          grid-template-columns: ${cssManager.cssGridColumns(this.menuOptions.length, 0)};
        }
      </style>
      <div class="modalContainer" @click=${this.handleOutsideClick}>
        <div class="modal">
          <div class="heading">${this.heading}</div>
          <div class="content">${this.content}</div>
          <div class="bottomButtons">
            ${this.menuOptions.map(
              (actionArg) => html`
                <div class="bottomButton" @click=${() => {
                  actionArg.action(this);
                }}>${actionArg.name}</div>
              `
            )}
          </div>
        </div>
      </div>
    `;
  }

  private windowLayer: DeesWindowLayer;
  public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
    super.firstUpdated(_changedProperties);
    const domtools = await this.domtoolsPromise;
    await domtools.convenience.smartdelay.delayFor(30);
    const modal = this.shadowRoot.querySelector('.modal');
    modal.classList.add('show');
  }

  public async handleOutsideClick(eventArg: MouseEvent) {
    eventArg.stopPropagation();
    const modalContainer = this.shadowRoot.querySelector('.modalContainer');
    if (eventArg.target === modalContainer) {
      await this.destroy();
    }
  }

  public async destroy() {
    const domtools = await this.domtoolsPromise;
    const modal = this.shadowRoot.querySelector('.modal');
    modal.classList.add('predestroy');
    await domtools.convenience.smartdelay.delayFor(200);
    document.body.removeChild(this);
    await this.windowLayer.destroy();
  }
}