declare const window: Window & {
  electronAPI?: {
    onUpdateAvailable?: (cb: (info: { version: string }) => void) => void;
    onUpdateDownloading?: (cb: (info: any) => void) => void;
    onUpdateProgress?: (cb: (progress: { percent: number }) => void) => void;
    onUpdateReady?: (cb: () => void) => void;
    onUpdateError?: (cb: (err: { message: string }) => void) => void;
    installUpdate?: () => void;
  };
};

export class UpdateBanner {
  private el: HTMLElement | null = null;
  private state: 'hidden' | 'available' | 'downloading' | 'ready' | 'error' = 'hidden';
  private progressPercent = 0;
  private version = '';
  private errorMsg = '';

  render(container: HTMLElement): void {
    this.el = document.createElement('div');
    this.el.className = 'update-banner-new';
    container.appendChild(this.el);

    this.bindElectronEvents();
  }

  private bindElectronEvents(): void {
    const api = window.electronAPI;
    if (!api) return;

    api.onUpdateAvailable?.((info) => {
      this.state = 'available';
      this.version = info.version;
      this.updateDisplay();
    });

    api.onUpdateDownloading?.(() => {
      this.state = 'downloading';
      this.progressPercent = 0;
      this.updateDisplay();
    });

    api.onUpdateProgress?.((progress) => {
      this.state = 'downloading';
      this.progressPercent = Math.round(progress.percent);
      this.updateDisplay();
    });

    api.onUpdateReady?.(() => {
      this.state = 'ready';
      // version was set in onUpdateAvailable
      this.updateDisplay();
    });

    api.onUpdateError?.((err) => {
      this.state = 'error';
      this.errorMsg = err.message;
      this.updateDisplay();
    });
  }

  private updateDisplay(): void {
    if (!this.el) return;

    this.el.className = `update-banner-new ${this.state}`;

    switch (this.state) {
      case 'hidden':
        this.el.innerHTML = '';
        return;

      case 'available':
        this.el.innerHTML =
          `<span class="upd-dot"></span>` +
          `<span class="upd-text">Mise \u00e0 jour disponible\u00a0: <strong>v${this.escHtml(this.version)}</strong> — T\u00e9l\u00e9chargement en cours…</span>`;
        break;

      case 'downloading':
        this.el.innerHTML =
          `<span class="upd-dot"></span>` +
          `<span class="upd-text">T\u00e9l\u00e9chargement de la mise \u00e0 jour…</span>` +
          `<div class="upd-bar-wrap"><div class="upd-bar-fill" style="width:${this.progressPercent}%"></div></div>` +
          `<span class="upd-percent">${this.progressPercent}\u00a0%</span>`;
        break;

      case 'ready': {
        this.el.innerHTML =
          `<span class="upd-dot"></span>` +
          `<span class="upd-text">Mise \u00e0 jour <strong>v${this.escHtml(this.version)}</strong> pr\u00eate !</span>` +
          `<button class="upd-install-btn" id="upd-install-btn">Installer et red\u00e9marrer</button>`;
        const btn = this.el.querySelector('#upd-install-btn') as HTMLElement | null;
        btn?.addEventListener('click', () => window.electronAPI?.installUpdate?.());
        break;
      }

      case 'error':
        this.el.innerHTML =
          `<span class="upd-dot"></span>` +
          `<span class="upd-text">Erreur de mise \u00e0 jour\u00a0: ${this.escHtml(this.errorMsg)}</span>` +
          `<button class="upd-dismiss-btn" id="upd-dismiss-btn">\u2715</button>`;
        const dismissBtn = this.el.querySelector('#upd-dismiss-btn') as HTMLElement | null;
        dismissBtn?.addEventListener('click', () => {
          this.state = 'hidden';
          this.updateDisplay();
        });
        break;
    }
  }

  private escHtml(s: string): string {
    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
  }

  destroy(): void {
    this.el?.remove();
    this.el = null;
  }
}
