import * as colors from '../00colors.js';
import * as plugins from '../00plugins.js';
import { zIndexLayers, zIndexRegistry } from '../00zindex.js';
import { cssGeistFontFamily } from '../00fonts.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/dees-windowlayer.js';
import '../dees-icon/dees-icon.js';
import { themeDefaultStyles } from '../00theme.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>[];
    width?: 'small' | 'medium' | 'large' | 'fullscreen' | number;
    maxWidth?: number;
    minWidth?: number;
    showCloseButton?: boolean;
    showHelpButton?: boolean;
    onHelp?: () => void | Promise<void>;
    mobileFullscreen?: boolean;
    contentPadding?: number;
  }) {
    const body = document.body;
    const modal = new DeesModal();
    modal.heading = optionsArg.heading;
    modal.content = optionsArg.content;
    modal.menuOptions = optionsArg.menuOptions;
    if (optionsArg.width) modal.width = optionsArg.width;
    if (optionsArg.maxWidth) modal.maxWidth = optionsArg.maxWidth;
    if (optionsArg.minWidth) modal.minWidth = optionsArg.minWidth;
    if (optionsArg.showCloseButton !== undefined) modal.showCloseButton = optionsArg.showCloseButton;
    if (optionsArg.showHelpButton !== undefined) modal.showHelpButton = optionsArg.showHelpButton;
    if (optionsArg.onHelp) modal.onHelp = optionsArg.onHelp;
    if (optionsArg.mobileFullscreen !== undefined) modal.mobileFullscreen = optionsArg.mobileFullscreen;
    if (optionsArg.contentPadding !== undefined) modal.contentPadding = optionsArg.contentPadding;
    modal.windowLayer = await DeesWindowLayer.createAndShow({
      blur: true,
    });
    modal.windowLayer.addEventListener('click', async () => {
      await modal.destroy();
    });
    body.append(modal.windowLayer);
    body.append(modal);
    
    // Get z-index for modal (should be above window layer)
    modal.modalZIndex = zIndexRegistry.getNextZIndex();
    zIndexRegistry.register(modal, modal.modalZIndex);
    
    return modal;
  }

  // INSTANCE

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

  @state({})
  accessor content: TemplateResult;

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

  @property({ type: String })
  accessor width: 'small' | 'medium' | 'large' | 'fullscreen' | number = 'medium';

  @property({ type: Number })
  accessor maxWidth: number;

  @property({ type: Number })
  accessor minWidth: number;

  @property({ type: Boolean })
  accessor showCloseButton: boolean = true;

  @property({ type: Boolean })
  accessor showHelpButton: boolean = false;

  @property({ attribute: false })
  accessor onHelp: () => void | Promise<void>;

  @property({ type: Boolean })
  accessor mobileFullscreen: boolean = false;

  @property({ type: Number })
  accessor contentPadding: number = 16;

  @state()
  accessor modalZIndex: number = 1000;

  constructor() {
    super();
  }

  public static styles = [
    themeDefaultStyles,
    cssManager.defaultStyles,
    css`
      /* TODO: Migrate hardcoded values to --dees-* CSS variables */
      :host {
        font-family: ${cssGeistFontFamily};
        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;
      }
      .modal {
        will-change: transform;
        transform: translateY(0px) scale(0.95);
        opacity: 0;
        min-height: 120px;
        max-height: calc(100vh - 40px);
        background: ${cssManager.bdTheme('#ffffff', '#09090b')};
        border-radius: 6px;
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
        transition: all 0.2s ease;
        overflow: hidden;
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
        margin: 20px;
        display: flex;
        flex-direction: column;
        overscroll-behavior: contain;
      }

      /* Width variations */
      .modal.width-small {
        width: 380px;
      }

      .modal.width-medium {
        width: 560px;
      }

      .modal.width-large {
        width: 800px;
      }

      .modal.width-fullscreen {
        width: calc(100vw - 40px);
        height: calc(100vh - 40px);
        max-height: calc(100vh - 40px);
      }

      @media (max-width: 768px) {
        .modal {
          width: calc(100vw - 40px) !important;
          max-width: none !important;
        }
        
        /* Allow full height on mobile when content needs it */
        .modalContainer {
          padding: 10px;
        }
        
        .modal {
          margin: 10px;
          max-height: calc(100vh - 20px);
        }
        
        /* Full screen mode on mobile */
        .modal.mobile-fullscreen {
          width: 100vw !important;
          height: 100vh !important;
          max-height: 100vh !important;
          margin: 0;
          border-radius: 0;
          border: none;
        }
      }

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

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

      .modal .heading {
        height: 40px;
        min-height: 40px;
        font-family: ${cssGeistFontFamily};
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0 12px;
        border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
        position: relative;
        flex-shrink: 0;
      }

      .modal .heading .header-buttons {
        display: flex;
        align-items: center;
        gap: 4px;
        position: absolute;
        right: 8px;
        top: 50%;
        transform: translateY(-50%);
      }

      .modal .heading .header-button {
        width: 28px;
        height: 28px;
        border-radius: 4px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: all 0.15s ease;
        background: transparent;
        color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
      }

      .modal .heading .header-button:hover {
        background: ${cssManager.bdTheme('#f4f4f5', '#27272a')};
        color: ${cssManager.bdTheme('#09090b', '#fafafa')};
      }

      .modal .heading .header-button:active {
        background: ${cssManager.bdTheme('#e5e7eb', '#3f3f46')};
      }

      .modal .heading .header-button dees-icon {
        width: 16px;
        height: 16px;
        display: block;
      }

      .modal .heading .heading-text {
        flex: 1;
        text-align: center;
        font-weight: 600;
        font-size: 14px;
        line-height: 40px;
        padding: 0 40px;
        color: ${cssManager.bdTheme('#09090b', '#fafafa')};
      }

      .modal .content {
        flex: 1;
        overflow-y: auto;
        overflow-x: hidden;
        overscroll-behavior: contain;
      }
      .modal .bottomButtons {
        display: flex;
        flex-direction: row;
        border-top: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
        justify-content: flex-end;
        gap: 8px;
        padding: 8px;
        flex-shrink: 0;
      }

      .modal .bottomButtons .bottomButton {
        padding: 8px 16px;
        border-radius: 4px;
        line-height: 16px;
        text-align: center;
        font-size: 14px;
        font-weight: 500;
        cursor: pointer;
        user-select: none;
        transition: all 0.15s ease;
        background: ${cssManager.bdTheme('#ffffff', '#27272a')};
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#3f3f46')};
        color: ${cssManager.bdTheme('#09090b', '#fafafa')};
        white-space: nowrap;
      }

      .modal .bottomButtons .bottomButton:hover {
        background: ${cssManager.bdTheme('#f4f4f5', '#3f3f46')};
        border-color: ${cssManager.bdTheme('#d1d5db', '#52525b')};
      }
      .modal .bottomButtons .bottomButton:active {
        background: ${cssManager.bdTheme('#e5e7eb', '#52525b')};
      }
      .modal .bottomButtons .bottomButton:last-child {
        border-right: none;
      }

      .modal .bottomButtons .bottomButton.primary {
        background: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
        border-color: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
        color: #ffffff;
      }
      .modal .bottomButtons .bottomButton.primary:hover {
        background: ${cssManager.bdTheme('#2563eb', '#2563eb')};
        border-color: ${cssManager.bdTheme('#2563eb', '#2563eb')};
      }
      .modal .bottomButtons .bottomButton.primary:active {
        background: ${cssManager.bdTheme('#1d4ed8', '#1d4ed8')};
        border-color: ${cssManager.bdTheme('#1d4ed8', '#1d4ed8')};
      }
    `,
  ];

  public render(): TemplateResult {
    const widthClass = typeof this.width === 'string' ? `width-${this.width}` : '';
    const customWidth = typeof this.width === 'number' ? `${this.width}px` : '';
    const maxWidthStyle = this.maxWidth ? `${this.maxWidth}px` : '';
    const minWidthStyle = this.minWidth ? `${this.minWidth}px` : '';
    const mobileFullscreenClass = this.mobileFullscreen ? 'mobile-fullscreen' : '';

    return html`
      <style>
        ${customWidth ? `.modal { width: ${customWidth}; }` : ''}
        ${maxWidthStyle ? `.modal { max-width: ${maxWidthStyle}; }` : ''}
        ${minWidthStyle ? `.modal { min-width: ${minWidthStyle}; }` : ''}
      </style>
      <div class="modalContainer" @click=${this.handleOutsideClick} style="z-index: ${this.modalZIndex}">
        <div class="modal ${widthClass} ${mobileFullscreenClass}">
          <div class="heading">
            <div class="heading-text">${this.heading}</div>
            <div class="header-buttons">
              ${this.showHelpButton ? html`
                <div class="header-button" @click=${this.handleHelp} title="Help">
                  <dees-icon .icon=${'lucide:helpCircle'}></dees-icon>
                </div>
              ` : ''}
              ${this.showCloseButton ? html`
                <div class="header-button" @click=${() => this.destroy()} title="Close">
                  <dees-icon .icon=${'lucide:x'}></dees-icon>
                </div>
              ` : ''}
            </div>
          </div>
          <div class="content" style="padding: ${this.contentPadding}px;">${this.content}</div>
          ${this.menuOptions.length > 0 ? html`
            <div class="bottomButtons">
              ${this.menuOptions.map(
                (actionArg, index) => html`
                  <div class="bottomButton ${index === this.menuOptions.length - 1 ? 'primary' : ''} ${actionArg.name === 'OK' ? 'ok' : ''}" @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();
    
    // Unregister from z-index registry
    zIndexRegistry.unregister(this);
  }

  private async handleHelp() {
    if (this.onHelp) {
      await this.onHelp();
    }
  }
}
