import { LitElement, css, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';

@customElement('arx-dialog')
export class EveDialog extends LitElement {
  @property({ type: String }) override title = '';
  @property({ type: Boolean }) open = false;
  @property({ type: Boolean }) closeOnOverlayClick = true;
  @property({ type: Boolean }) closeOnEscape = true;
  @property({ type: String }) width = '420px';
  @property({ type: String }) maxWidth = '90%';

  private rootWindow: HTMLDivElement | null = null;
  private previousScrollTop = 0;

  static override styles = css`
    ::-webkit-scrollbar {
      width: 12px;
      height: 12px;
    }

    ::-webkit-scrollbar-track {
      background: var(--color-base-200);
      border-radius: var(--radius-field);
    }

    ::-webkit-scrollbar-thumb {
      background: var(--color-base-300);
      border-radius: var(--radius-field);
      border: 2px solid var(--color-base-200);
      transition: var(--transition);
    }

    ::-webkit-scrollbar-thumb:hover {
      background: var(--color-neutral);
    }

    :host {
      display: none;
      position: fixed !important;
      transform: translate3d(-50%, -50%, 1px);
      will-change: transform;
      top: 50%;
      left: 50%;
      width: 100vw;
      height: 100vh;
      z-index: 2147483647 !important;
      contain: layout;
      background-color: oklch(from var(--color-base-content) l c h / 0.6);
      overflow: hidden;
      -webkit-app-region: no-drag;
      backdrop-filter: blur(4px);
    }

    :host([open]) {
      display: block !important;
    }

    .dialog-container {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      max-height: 80vh;
      overflow: auto;
      background-color: var(--color-base-100);
      border-radius: var(--radius-box);
      border: var(--border) solid var(--color-base-300);
      box-shadow: calc(var(--depth) * 4px) calc(var(--depth) * 4px)
          calc(var(--depth) * 8px)
          oklch(from var(--color-base-content) l c h / 0.2),
        calc(var(--depth) * -1px) calc(var(--depth) * -1px)
          calc(var(--depth) * 4px) oklch(from var(--color-base-100) l c h / 0.4);
      width: var(--dialog-width, 420px);
      max-width: var(--dialog-max-width, 90%);
      padding: 28px;
      transition: transform 0.25s cubic-bezier(0.1, 1, 0.2, 1);
      color: var(--color-base-content);
    }

    .dialog-header {
      font-size: 18px;
      font-weight: 600;
      margin: 0 0 16px 0;
      line-height: 1.4;
      color: var(--color-base-content);
    }

    .dialog-content {
      overflow: auto;
      margin-bottom: 24px;
    }

    .dialog-footer {
      display: flex;
      justify-content: flex-end;
      gap: 12px;
    }

    .dialog-container:focus-within {
      box-shadow: calc(var(--depth) * 4px) calc(var(--depth) * 4px)
          calc(var(--depth) * 8px)
          oklch(from var(--color-base-content) l c h / 0.2),
        calc(var(--depth) * -1px) calc(var(--depth) * -1px)
          calc(var(--depth) * 4px) oklch(from var(--color-base-100) l c h / 0.4),
        0 0 0 2px oklch(from var(--color-accent) l c h / 0.2);
    }
  `;

  constructor() {
    super();
    this._handleKeyDown = this._handleKeyDown.bind(this);
  }

  override connectedCallback() {
    super.connectedCallback();
    document.addEventListener('keydown', this._handleKeyDown);
    const router = document.querySelector('arx-eve-router');
    if (router) {
      this.rootWindow = router.shadowRoot!.querySelector('.window') as HTMLDivElement;
    } else {
      this.rootWindow = document.body as HTMLDivElement;
    }
  }

  override disconnectedCallback() {
    super.disconnectedCallback();
    document.removeEventListener('keydown', this._handleKeyDown);
  }

  override updated(changedProps: Map<string, unknown>) {
    if (changedProps.has('open')) {
      if (this.open) this.show();
      else this.close();
    }
  }

  private _handleKeyDown(e: KeyboardEvent) {
    if (!this.open || !this.closeOnEscape) return;
    if (e.key === 'Escape') this.close();
  }

  private _handleOverlayClick(e: MouseEvent) {
    if (this.closeOnOverlayClick && e.target === e.currentTarget) this.close();
  }

  show() {
    this.open = true;
    this.style.display = 'block';
    this.previousScrollTop = this.rootWindow?.scrollTop ?? 0;
    this.style.height = `${this.rootWindow!.clientHeight * 2}px`; // this is a hack to prevent the overlay background from showing through
    this.rootWindow?.style.setProperty('overflow', 'hidden', 'important');
    this.rootWindow?.scrollTo({
      top: 0,
      behavior: 'smooth',
    });
  }

  close(triggerEvent = true) {
    this.open = false;
    this.style.display = 'none';
    this.rootWindow?.style.setProperty('overflow', 'auto', 'important');
    this.rootWindow?.scrollTo({
      top: this.previousScrollTop,
      behavior: 'smooth',
    });
    if (triggerEvent) this.dispatchEvent(new CustomEvent('close'));
  }

  override render() {
    return html`
      <div
        class=${classMap({ active: this.open })}
        @click=${this._handleOverlayClick}
        style="--dialog-width: ${this.width}; --dialog-max-width: ${this.maxWidth};"
      >
        <div class="dialog-container" tabindex="-1">
          ${this.title ? html`<div class="dialog-header">${this.title}</div>` : ''}
          <div class="dialog-content">
            <slot></slot>
          </div>
          <div class="dialog-footer">
            <slot name="footer"></slot>
          </div>
        </div>
      </div>
    `;
  }
}
