/**
 * admin-ui/js/components/ds-toast.js
 * A single toast notification component with swipe-to-dismiss support.
 */
class DsToast extends HTMLElement {
  static get observedAttributes() {
    return ['type', 'duration'];
  }

  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this._duration = 5000;
    this._dismissTimer = null;
  }

  connectedCallback() {
    this.render();
    this.setupAutoDismiss();
    this.setupSwipeToDismiss();
    this.shadowRoot.querySelector('.close-button')?.addEventListener('click', () => this.dismiss());
  }

  disconnectedCallback() {
    if (this._dismissTimer) {
      clearTimeout(this._dismissTimer);
    }
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'duration') {
      this._duration = parseInt(newValue, 10);
    }
  }

  setupAutoDismiss() {
    if (this._duration > 0 && !this.hasAttribute('progress')) {
      this._dismissTimer = setTimeout(() => this.dismiss(), this._duration);
    }
  }

  dismiss() {
    if (this._dismissTimer) {
      clearTimeout(this._dismissTimer);
    }
    this.classList.add('dismissing');
    this.addEventListener('animationend', () => {
      this.dispatchEvent(new CustomEvent('dismiss', { bubbles: true, composed: true }));
      this.remove();
    }, { once: true });
  }

  setupSwipeToDismiss() {
    let startX = 0;
    let currentX = 0;
    let isDragging = false;

    this.addEventListener('pointerdown', (e) => {
      isDragging = true;
      startX = e.clientX;
      currentX = startX;
      this.style.transition = 'none';
      this.setPointerCapture(e.pointerId);
    });

    this.addEventListener('pointermove', (e) => {
      if (!isDragging) return;
      currentX = e.clientX;
      const diff = currentX - startX;
      this.style.transform = `translateX(${diff}px)`;
    });

    const onPointerUp = (e) => {
      if (!isDragging) return;
      isDragging = false;
      this.style.transition = 'transform 0.2s ease';
      const diff = currentX - startX;
      const threshold = this.offsetWidth * 0.3;

      if (Math.abs(diff) > threshold) {
        this.style.transform = `translateX(${diff > 0 ? '100%' : '-100%'})`;
        this.dismiss();
      } else {
        this.style.transform = 'translateX(0)';
      }
    };

    this.addEventListener('pointerup', onPointerUp);
    this.addEventListener('pointercancel', onPointerUp);
  }

  render() {
    const type = this.getAttribute('type') || 'info';
    const dismissible = this.hasAttribute('dismissible');

    this.shadowRoot.innerHTML = `
      <style>
        :host {
          display: flex;
          align-items: center;
          gap: var(--space-3);
          background: var(--card);
          color: var(--card-foreground);
          border: 1px solid var(--border);
          border-left: 4px solid var(--primary);
          padding: var(--space-3) var(--space-4);
          border-radius: var(--radius-lg);
          box-shadow: var(--shadow-lg);
          transform-origin: top center;
          animation: slide-in 0.3s ease forwards;
          will-change: transform, opacity;
          cursor: grab;
          touch-action: pan-y;
        }
        :host([type="success"]) { border-left-color: var(--success); }
        :host([type="warning"]) { border-left-color: var(--warning); }
        :host([type="error"]) { border-left-color: var(--destructive); }
        :host(.dismissing) {
          animation: slide-out 0.3s ease forwards;
        }
        .content {
          flex: 1;
          font-size: var(--text-sm);
          line-height: 1.4;
        }
        .close-button {
          background: none;
          border: none;
          color: var(--muted-foreground);
          padding: var(--space-1);
          cursor: pointer;
          width: 1.5rem;
          height: 1.5rem;
          display: flex;
          align-items: center;
          justify-content: center;
          border-radius: var(--radius);
          transition: background 0.15s ease;
        }
        .close-button:hover {
          background: var(--accent);
          color: var(--foreground);
        }
        @keyframes slide-in {
          from { opacity: 0; transform: translateY(-20px) scale(0.95); }
          to { opacity: 1; transform: translateY(0) scale(1); }
        }
        @keyframes slide-out {
          from { opacity: 1; transform: translateY(0) scale(1); }
          to { opacity: 0; transform: translateY(-20px) scale(0.95); }
        }
      </style>
      <div class="icon"><slot name="icon"></slot></div>
      <div class="content">
        <slot></slot>
      </div>
      ${dismissible ? `<button class="close-button" aria-label="Dismiss">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="18" y1="6" x2="6" y2="18"></line>
          <line x1="6" y1="6" x2="18" y2="18"></line>
        </svg>
      </button>` : ''}
    `;
  }
}

customElements.define('ds-toast', DsToast);
