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

import * as domtools from '@design.estate/dees-domtools';
import { zIndexLayers } from '../00zindex.js';
import { demoFunc } from './dees-toast.demo.js';
import { cssGeistFontFamily } from '../00fonts.js';
import { themeDefaultStyles } from '../00theme.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-toast': DeesToast;
  }
}

export type ToastType = 'info' | 'success' | 'warning' | 'error';
export type ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';

export interface IToastOptions {
  message: string;
  type?: ToastType;
  duration?: number;
  position?: ToastPosition;
}

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

  private static toastContainers = new Map<ToastPosition, HTMLDivElement>();

  private static getOrCreateContainer(position: ToastPosition): HTMLDivElement {
    if (!this.toastContainers.has(position)) {
      const container = document.createElement('div');
      container.className = `toast-container toast-container-${position}`;
      container.style.cssText = `
        position: fixed;
        z-index: ${zIndexLayers.overlay.toast};
        pointer-events: none;
        padding: 16px;
        display: flex;
        flex-direction: column;
        gap: 8px;
      `;

      // Position the container
      switch (position) {
        case 'top-right':
          container.style.top = '0';
          container.style.right = '0';
          break;
        case 'top-left':
          container.style.top = '0';
          container.style.left = '0';
          break;
        case 'bottom-right':
          container.style.bottom = '0';
          container.style.right = '0';
          break;
        case 'bottom-left':
          container.style.bottom = '0';
          container.style.left = '0';
          break;
        case 'top-center':
          container.style.top = '0';
          container.style.left = '50%';
          container.style.transform = 'translateX(-50%)';
          break;
        case 'bottom-center':
          container.style.bottom = '0';
          container.style.left = '50%';
          container.style.transform = 'translateX(-50%)';
          break;
      }

      document.body.appendChild(container);
      this.toastContainers.set(position, container);
    }
    return this.toastContainers.get(position)!;
  }

  public static async show(options: IToastOptions | string) {
    const opts: IToastOptions = typeof options === 'string' 
      ? { message: options } 
      : options;

    const toast = new DeesToast();
    toast.message = opts.message;
    toast.type = opts.type || 'info';
    toast.duration = opts.duration || 3000;

    const container = this.getOrCreateContainer(opts.position || 'top-right');
    container.appendChild(toast);

    // Trigger animation
    await toast.updateComplete;
    requestAnimationFrame(() => {
      toast.isVisible = true;
    });

    // Auto dismiss
    if (toast.duration > 0) {
      setTimeout(() => {
        toast.dismiss();
      }, toast.duration);
    }

    return toast;
  }

  // Alias for consistency with DeesModal
  public static async createAndShow(options: IToastOptions | string) {
    return this.show(options);
  }

  // Convenience methods
  public static info(message: string, duration?: number) {
    return this.show({ message, type: 'info', duration });
  }

  public static success(message: string, duration?: number) {
    return this.show({ message, type: 'success', duration });
  }

  public static warning(message: string, duration?: number) {
    return this.show({ message, type: 'warning', duration });
  }

  public static error(message: string, duration?: number) {
    return this.show({ message, type: 'error', duration });
  }

  // INSTANCE
  @property({ type: String })
  accessor message: string = '';

  @property({ type: String })
  accessor type: ToastType = 'info';

  @property({ type: Number })
  accessor duration: number = 3000;

  @property({ type: Boolean, reflect: true })
  accessor isVisible: boolean = false;

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

  public static styles = [
    themeDefaultStyles,
    cssManager.defaultStyles,
    css`
      /* TODO: Migrate hardcoded values to --dees-* CSS variables */
      :host {
        display: block;
        pointer-events: auto;
        font-family: ${cssGeistFontFamily};
        opacity: 0;
        transform: translateY(-10px);
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }

      :host([isvisible]) {
        opacity: 1;
        transform: translateY(0);
      }

      .toast {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 16px 20px;
        border-radius: 8px;
        background: ${cssManager.bdTheme('#fff', '#222')};
        border: 1px solid ${cssManager.bdTheme('#e0e0e0', '#333')};
        box-shadow: 0 4px 12px ${cssManager.bdTheme('rgba(0,0,0,0.1)', 'rgba(0,0,0,0.3)')};
        min-width: 300px;
        max-width: 500px;
        cursor: pointer;
      }

      .toast:hover {
        transform: scale(1.02);
      }

      .icon {
        flex-shrink: 0;
        width: 20px;
        height: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .icon svg {
        width: 100%;
        height: 100%;
      }

      .message {
        flex: 1;
        font-size: 14px;
        line-height: 1.5;
        color: ${cssManager.bdTheme('#333', '#fff')};
      }

      .close {
        flex-shrink: 0;
        width: 16px;
        height: 16px;
        opacity: 0.5;
        cursor: pointer;
        transition: opacity 0.2s;
      }

      .close:hover {
        opacity: 1;
      }

      .close svg {
        width: 100%;
        height: 100%;
        fill: currentColor;
      }

      /* Type-specific styles */
      :host([type="info"]) .icon {
        color: #0084ff;
      }

      :host([type="success"]) .icon {
        color: #22c55e;
      }

      :host([type="warning"]) .icon {
        color: #f59e0b;
      }

      :host([type="error"]) .icon {
        color: #ef4444;
      }

      /* Progress bar */
      .progress {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 3px;
        background: currentColor;
        opacity: 0.2;
        border-radius: 0 0 8px 8px;
        overflow: hidden;
      }

      .progress-bar {
        height: 100%;
        background: currentColor;
        opacity: 0.8;
        transform-origin: left;
        animation: progress linear forwards;
      }

      @keyframes progress {
        from {
          transform: scaleX(1);
        }
        to {
          transform: scaleX(0);
        }
      }
    `
  ];

  public render(): TemplateResult {
    const icons = {
      info: html`<svg viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z" clip-rule="evenodd"/>
      </svg>`,
      success: html`<svg viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
      </svg>`,
      warning: html`<svg viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
      </svg>`,
      error: html`<svg viewBox="0 0 20 20" fill="currentColor">
        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
      </svg>`
    };

    return html`
      <div class="toast" @click=${this.dismiss}>
        <div class="icon">
          ${icons[this.type]}
        </div>
        <div class="message">${this.message}</div>
        <div class="close">
          <svg viewBox="0 0 16 16" fill="currentColor">
            <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
          </svg>
        </div>
        ${this.duration > 0 ? html`
          <div class="progress">
            <div class="progress-bar" style="animation-duration: ${this.duration}ms"></div>
          </div>
        ` : ''}
      </div>
    `;
  }

  public async dismiss() {
    this.isVisible = false;
    await new Promise(resolve => setTimeout(resolve, 300));
    this.remove();
    
    // Clean up empty containers
    const container = this.parentElement;
    if (container && container.children.length === 0) {
      container.remove();
      for (const [position, cont] of DeesToast.toastContainers.entries()) {
        if (cont === container) {
          DeesToast.toastContainers.delete(position);
          break;
        }
      }
    }
  }

  public firstUpdated() {
    // Set the type attribute for CSS
    this.setAttribute('type', this.type);
  }
}