import {
  customElement,
  DeesElement,
  type TemplateResult,
  html,
  css,
  state,
  cssManager,
} from '@design.estate/dees-element';
import { themeDefaultStyles } from '../00theme.js';
import '../dees-icon/dees-icon.js';
import type {
  IActionBarOptions,
  IActionBarResult,
  IActionBarQueueItem,
  IActionBarAction,
} from './actionbar.interfaces.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-actionbar': DeesActionbar;
  }
}

@customElement('dees-actionbar')
export class DeesActionbar extends DeesElement {
  // STATIC
  public static demo = () => {
    const getActionbar = (e: Event) => {
      const button = e.currentTarget as HTMLElement;
      const container = button.closest('.demo-container');
      return container?.querySelector('dees-actionbar') as DeesActionbar | null;
    };

    const showActionBar = async (e: Event) => {
      const actionbar = getActionbar(e);
      if (!actionbar) return;
      const result = await actionbar.show({
        message: 'File changed externally. Reload?',
        type: 'warning',
        icon: 'lucide:alertTriangle',
        actions: [
          { id: 'reload', label: 'Reload', primary: true },
          { id: 'ignore', label: 'Ignore' },
        ],
        timeout: { duration: 5000, defaultActionId: 'reload' },
        dismissible: true,
      });
      console.log('Action bar result:', result);
    };

    const showErrorBar = async (e: Event) => {
      const actionbar = getActionbar(e);
      if (!actionbar) return;
      const result = await actionbar.show({
        message: 'Process failed with exit code 1',
        type: 'error',
        icon: 'lucide:xCircle',
        actions: [
          { id: 'retry', label: 'Retry', primary: true },
          { id: 'dismiss', label: 'Dismiss' },
        ],
        timeout: { duration: 10000, defaultActionId: 'dismiss' },
      });
      console.log('Error bar result:', result);
    };

    const showQuestionBar = async (e: Event) => {
      const actionbar = getActionbar(e);
      if (!actionbar) return;
      const result = await actionbar.show({
        message: 'Save changes before closing?',
        type: 'question',
        icon: 'lucide:helpCircle',
        actions: [
          { id: 'save', label: 'Save', primary: true },
          { id: 'discard', label: 'Discard' },
          { id: 'cancel', label: 'Cancel' },
        ],
      });
      console.log('Question bar result:', result);
    };

    return html`
      <style>
        .demo-container {
          display: flex;
          flex-direction: column;
          height: 300px;
          border: 1px solid #333;
          border-radius: 8px;
          overflow: hidden;
        }
        .demo-content {
          flex: 1;
          padding: 16px;
          display: flex;
          gap: 8px;
          align-items: flex-start;
        }
      </style>
      <div class="demo-container">
        <div class="demo-content">
          <dees-button @click=${showActionBar}>Warning</dees-button>
          <dees-button @click=${showErrorBar}>Error</dees-button>
          <dees-button @click=${showQuestionBar}>Question</dees-button>
        </div>
        <dees-actionbar></dees-actionbar>
      </div>
    `;
  };

  // Queue of pending action bars
  private queue: IActionBarQueueItem[] = [];

  // Current active bar state
  @state() accessor currentBar: IActionBarOptions | null = null;
  @state() accessor timeRemaining: number = 0;
  @state() accessor progressPercent: number = 100;
  @state() accessor isVisible: boolean = false;

  // Timeout handling
  private timeoutInterval: ReturnType<typeof setInterval> | null = null;
  private currentResolve: ((result: IActionBarResult) => void) | null = null;

  public static styles = [
    themeDefaultStyles,
    cssManager.defaultStyles,
    css`
      :host {
        display: block;
      }

      .actionbar-item {
        display: grid;
        grid-template-rows: 0fr;
        transition: grid-template-rows 0.2s ease-out;
        background: ${cssManager.bdTheme('hsl(0 0% 96%)', 'hsl(0 0% 12%)')};
        border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 88%)', 'hsl(0 0% 20%)')};
      }

      :host(.visible) .actionbar-item {
        grid-template-rows: 1fr;
      }

      .actionbar-content {
        overflow: hidden;
        min-height: 0;
        opacity: 0;
        transition: opacity 0.2s ease-out;
      }

      :host(.visible) .actionbar-content {
        opacity: 1;
      }

      .progress-bar {
        height: 3px;
        background: ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(0 0% 18%)')};
        overflow: hidden;
      }

      .progress-bar-fill {
        height: 100%;
        background: ${cssManager.bdTheme('hsl(210 100% 50%)', 'hsl(210 100% 60%)')};
        transition: width 0.1s linear;
      }

      .progress-bar-fill.warning {
        background: ${cssManager.bdTheme('hsl(38 92% 50%)', 'hsl(38 92% 55%)')};
      }

      .progress-bar-fill.error {
        background: ${cssManager.bdTheme('hsl(0 70% 50%)', 'hsl(0 70% 55%)')};
      }

      .progress-bar-fill.question {
        background: ${cssManager.bdTheme('hsl(270 70% 50%)', 'hsl(270 70% 60%)')};
      }

      .content {
        display: flex;
        align-items: center;
        padding: 8px 12px;
        gap: 12px;
        min-height: 32px;
      }

      .message-section {
        display: flex;
        align-items: center;
        gap: 8px;
        flex: 1;
        min-width: 0;
      }

      .message-icon {
        flex-shrink: 0;
        color: ${cssManager.bdTheme('hsl(0 0% 40%)', 'hsl(0 0% 60%)')};
      }

      .message-icon.info {
        color: ${cssManager.bdTheme('hsl(210 100% 45%)', 'hsl(210 100% 60%)')};
      }

      .message-icon.warning {
        color: ${cssManager.bdTheme('hsl(38 92% 45%)', 'hsl(38 92% 55%)')};
      }

      .message-icon.error {
        color: ${cssManager.bdTheme('hsl(0 70% 50%)', 'hsl(0 70% 55%)')};
      }

      .message-icon.question {
        color: ${cssManager.bdTheme('hsl(270 70% 50%)', 'hsl(270 70% 60%)')};
      }

      .message-text {
        font-size: 13px;
        color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 85%)')};
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .actions-section {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-shrink: 0;
      }

      .action-button {
        display: flex;
        align-items: center;
        gap: 4px;
        padding: 4px 10px;
        border-radius: 4px;
        font-size: 12px;
        font-weight: 500;
        cursor: pointer;
        border: 1px solid transparent;
        transition: all 0.15s ease;
        white-space: nowrap;
      }

      .action-button.secondary {
        background: transparent;
        color: ${cssManager.bdTheme('hsl(0 0% 30%)', 'hsl(0 0% 70%)')};
        border-color: ${cssManager.bdTheme('hsl(0 0% 80%)', 'hsl(0 0% 30%)')};
      }

      .action-button.secondary:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 92%)', 'hsl(0 0% 18%)')};
      }

      .action-button.primary {
        background: ${cssManager.bdTheme('hsl(210 100% 50%)', 'hsl(210 100% 55%)')};
        color: white;
      }

      .action-button.primary:hover {
        background: ${cssManager.bdTheme('hsl(210 100% 45%)', 'hsl(210 100% 50%)')};
      }

      .action-button.primary.warning {
        background: ${cssManager.bdTheme('hsl(38 92% 45%)', 'hsl(38 92% 50%)')};
      }

      .action-button.primary.warning:hover {
        background: ${cssManager.bdTheme('hsl(38 92% 40%)', 'hsl(38 92% 45%)')};
      }

      .action-button.primary.error {
        background: ${cssManager.bdTheme('hsl(0 70% 50%)', 'hsl(0 70% 55%)')};
      }

      .action-button.primary.error:hover {
        background: ${cssManager.bdTheme('hsl(0 70% 45%)', 'hsl(0 70% 50%)')};
      }

      .action-button.primary.question {
        background: ${cssManager.bdTheme('hsl(270 70% 50%)', 'hsl(270 70% 55%)')};
      }

      .action-button.primary.question:hover {
        background: ${cssManager.bdTheme('hsl(270 70% 45%)', 'hsl(270 70% 50%)')};
      }

      .countdown {
        font-size: 11px;
        opacity: 0.8;
        margin-left: 2px;
      }

      .dismiss-button {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 20px;
        height: 20px;
        border-radius: 4px;
        cursor: pointer;
        color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 50%)')};
        transition: all 0.15s ease;
      }

      .dismiss-button:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 88%)', 'hsl(0 0% 22%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 30%)', 'hsl(0 0% 70%)')};
      }
    `,
  ];

  public render(): TemplateResult {
    const bar = this.currentBar;
    const type = bar?.type || 'info';
    const hasTimeout = bar?.timeout && this.timeRemaining > 0;

    // ALWAYS render wrapper - required for grid animation to work
    return html`
      <div class="actionbar-item">
        <div class="actionbar-content">
          ${bar ? html`
            ${hasTimeout ? html`
              <div class="progress-bar">
                <div
                  class="progress-bar-fill ${type}"
                  style="width: ${this.progressPercent}%"
                ></div>
              </div>
            ` : ''}
            <div class="content">
              <div class="message-section">
                ${bar.icon ? html`
                  <dees-icon
                    class="message-icon ${type}"
                    .icon=${bar.icon}
                    iconSize="16"
                  ></dees-icon>
                ` : ''}
                <span class="message-text">${bar.message}</span>
              </div>
              <div class="actions-section">
                ${bar.actions.map(action => this.renderActionButton(action, bar, hasTimeout))}
                ${bar.dismissible ? html`
                  <div
                    class="dismiss-button"
                    @click=${() => this.handleDismiss()}
                    title="Dismiss"
                  >
                    <dees-icon .icon=${'lucide:x'} iconSize="14"></dees-icon>
                  </div>
                ` : ''}
              </div>
            </div>
          ` : ''}
        </div>
      </div>
    `;
  }

  private renderActionButton(
    action: IActionBarAction,
    bar: IActionBarOptions,
    hasTimeout: boolean | undefined
  ): TemplateResult {
    const isPrimary = action.primary;
    const type = bar.type || 'info';
    const isDefaultAction = bar.timeout?.defaultActionId === action.id;
    const showCountdown = hasTimeout && isDefaultAction;
    const seconds = Math.ceil(this.timeRemaining / 1000);

    return html`
      <button
        class="action-button ${isPrimary ? `primary ${type}` : 'secondary'}"
        @click=${() => this.handleAction(action.id, false)}
      >
        ${action.icon ? html`
          <dees-icon .icon=${action.icon} iconSize="12"></dees-icon>
        ` : ''}
        <span>${action.label}</span>
        ${showCountdown ? html`
          <span class="countdown">(${seconds}s)</span>
        ` : ''}
      </button>
    `;
  }

  // ========== Public API ==========

  /**
   * Show an action bar with the given options.
   * Returns a promise that resolves when an action is taken.
   */
  public async show(options: IActionBarOptions): Promise<IActionBarResult> {
    return new Promise((resolve) => {
      // Add to queue
      this.queue.push({ options, resolve });

      // If no current bar, process queue
      if (!this.currentBar) {
        this.processQueue();
      }
    });
  }

  /**
   * Dismiss the current action bar without triggering any action.
   */
  public dismiss(): void {
    this.handleDismiss();
  }

  /**
   * Clear all pending action bars in the queue.
   */
  public clearQueue(): void {
    // Resolve all queued items with dismiss
    for (const item of this.queue) {
      item.resolve({ actionId: 'dismissed', timedOut: false });
    }
    this.queue = [];
  }

  // ========== Private Methods ==========

  /**
   * Hide the current actionbar with animation.
   * Removes visible class first to trigger CSS transition, then clears content after animation.
   */
  private async hideCurrentBar(): Promise<void> {
    // Remove visible class to start close animation
    this.classList.remove('visible');
    this.isVisible = false;

    // Wait for animation to complete (200ms transition + buffer)
    await new Promise(resolve => setTimeout(resolve, 220));

    // Now safe to clear content
    this.currentBar = null;
    this.currentResolve = null;
  }

  private async processQueue(): Promise<void> {
    if (this.queue.length === 0) {
      // Hide with animation - don't await, let it run async
      this.hideCurrentBar();
      return;
    }

    const item = this.queue.shift()!;
    this.currentBar = item.options;
    this.currentResolve = item.resolve;
    this.isVisible = true;

    // Wait for Lit render, then add class on next frame to trigger animation
    await this.updateComplete;
    requestAnimationFrame(() => {
      this.classList.add('visible');
    });

    // Setup timeout if configured
    if (item.options.timeout) {
      this.startTimeout(item.options.timeout.duration, item.options.timeout.defaultActionId);
    }
  }

  private startTimeout(duration: number, defaultActionId: string): void {
    this.timeRemaining = duration;
    this.progressPercent = 100;

    const startTime = Date.now();
    const updateInterval = 50; // Update every 50ms for smooth animation

    this.timeoutInterval = setInterval(() => {
      const elapsed = Date.now() - startTime;
      this.timeRemaining = Math.max(0, duration - elapsed);
      this.progressPercent = (this.timeRemaining / duration) * 100;

      if (this.timeRemaining <= 0) {
        this.clearTimeoutInterval();
        this.handleAction(defaultActionId, true);
      }
    }, updateInterval);
  }

  private clearTimeoutInterval(): void {
    if (this.timeoutInterval) {
      clearInterval(this.timeoutInterval);
      this.timeoutInterval = null;
    }
  }

  private handleAction(actionId: string, timedOut: boolean): void {
    this.clearTimeoutInterval();

    if (this.currentResolve) {
      this.currentResolve({ actionId, timedOut });
    }

    // Process next item in queue
    this.processQueue();
  }

  private handleDismiss(): void {
    this.handleAction('dismissed', false);
  }

  public async disconnectedCallback(): Promise<void> {
    await super.disconnectedCallback();
    this.clearTimeoutInterval();
  }
}
