/**
 * Tractatus Version Manager
 * - Registers service worker
 * - Checks for updates every hour
 * - Shows update notifications
 * - Manages PWA install prompts
 */

class VersionManager {
  constructor() {
    this.serviceWorker = null;
    this.deferredInstallPrompt = null;
    this.updateCheckInterval = null;
    this.currentVersion = null;

    this.init();
  }

  async init() {
    // Only run in browsers that support service workers
    if (!('serviceWorker' in navigator)) {
      console.log('[VersionManager] Service workers not supported');
      return;
    }

    try {
      // Register service worker
      await this.registerServiceWorker();

      // Check for updates immediately
      await this.checkForUpdates();

      // Check for updates every hour
      this.updateCheckInterval = setInterval(() => {
        this.checkForUpdates();
      }, 3600000); // 1 hour

      // Listen for PWA install prompt
      this.setupInstallPrompt();

      // Listen for service worker messages
      navigator.serviceWorker.addEventListener('message', (event) => {
        if (event.data.type === 'UPDATE_AVAILABLE') {
          this.showUpdateNotification(event.data);
        }
      });

    } catch (error) {
      console.error('[VersionManager] Initialization failed:', error);
    }
  }

  async registerServiceWorker() {
    try {
      const registration = await navigator.serviceWorker.register('/service-worker.js');
      this.serviceWorker = registration;
      console.log('[VersionManager] Service worker registered');

      // Check for updates when service worker updates
      registration.addEventListener('updatefound', () => {
        const newWorker = registration.installing;
        newWorker.addEventListener('statechange', () => {
          if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
            // New service worker available
            this.showUpdateNotification({
              updateAvailable: true,
              currentVersion: this.currentVersion,
              serverVersion: 'latest'
            });
          }
        });
      });

    } catch (error) {
      console.error('[VersionManager] Service worker registration failed:', error);
    }
  }

  async checkForUpdates() {
    try {
      const response = await fetch('/version.json', { cache: 'no-store' });
      const versionInfo = await response.json();

      // Get current version from localStorage or default
      const storedVersion = localStorage.getItem('tractatus_version') || '0.0.0';
      this.currentVersion = storedVersion;

      if (storedVersion !== versionInfo.version) {
        console.log('[VersionManager] Update available:', versionInfo.version);
        this.showUpdateNotification({
          updateAvailable: true,
          currentVersion: storedVersion,
          serverVersion: versionInfo.version,
          changelog: versionInfo.changelog,
          forceUpdate: versionInfo.forceUpdate
        });
      }

    } catch (error) {
      console.error('[VersionManager] Version check failed:', error);
    }
  }

  showUpdateNotification(versionInfo) {
    // Don't show if notification already visible
    if (document.getElementById('tractatus-update-notification')) {
      return;
    }

    const notification = document.createElement('div');
    notification.id = 'tractatus-update-notification';
    notification.className = 'fixed bottom-0 left-0 right-0 bg-blue-600 text-white px-4 py-3 shadow-lg z-50 transform transition-transform duration-300 translate-y-full';
    notification.innerHTML = `
      <div class="max-w-7xl mx-auto flex items-center justify-between flex-wrap gap-4">
        <div class="flex items-start flex-1">
          <svg class="w-6 h-6 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
          </svg>
          <div>
            <p class="font-semibold">Update Available</p>
            <p class="text-sm text-blue-100">
              A new version of Tractatus Framework is available
              ${versionInfo.serverVersion ? `(v${versionInfo.serverVersion})` : ''}
            </p>
            ${versionInfo.changelog ? `
              <details class="mt-2 text-sm">
                <summary class="cursor-pointer text-blue-100 hover:text-white">What's new?</summary>
                <ul class="mt-2 ml-4 list-disc text-blue-100">
                  ${versionInfo.changelog.map(item => `<li>${item}</li>`).join('')}
                </ul>
              </details>
            ` : ''}
          </div>
        </div>
        <div class="flex gap-3">
          ${versionInfo.forceUpdate ? `
            <button onclick="window.versionManager.applyUpdate()" class="bg-white text-blue-600 px-6 py-2 rounded-lg font-semibold hover:bg-blue-50 transition">
              Update Now
            </button>
          ` : `
            <button onclick="window.versionManager.dismissUpdate()" class="text-white hover:text-blue-100 transition px-3">
              Later
            </button>
            <button onclick="window.versionManager.applyUpdate()" class="bg-white text-blue-600 px-6 py-2 rounded-lg font-semibold hover:bg-blue-50 transition">
              Reload
            </button>
          `}
        </div>
      </div>
    `;

    document.body.appendChild(notification);

    // Animate in
    setTimeout(() => {
      notification.classList.remove('translate-y-full');
    }, 100);

    // Auto-reload for forced updates after 10 seconds
    if (versionInfo.forceUpdate) {
      setTimeout(() => {
        this.applyUpdate();
      }, 10000);
    }
  }

  applyUpdate() {
    // Store new version
    fetch('/version.json', { cache: 'no-store' })
      .then(response => response.json())
      .then(versionInfo => {
        localStorage.setItem('tractatus_version', versionInfo.version);

        // Tell service worker to skip waiting
        if (this.serviceWorker) {
          this.serviceWorker.waiting?.postMessage({ type: 'SKIP_WAITING' });
        }

        // Reload page
        window.location.reload();
      });
  }

  dismissUpdate() {
    const notification = document.getElementById('tractatus-update-notification');
    if (notification) {
      notification.classList.add('translate-y-full');
      setTimeout(() => {
        notification.remove();
      }, 300);
    }
  }

  setupInstallPrompt() {
    // Listen for beforeinstallprompt event
    window.addEventListener('beforeinstallprompt', (e) => {
      // Prevent Chrome 67 and earlier from automatically showing the prompt
      e.preventDefault();

      // Stash the event so it can be triggered later
      this.deferredInstallPrompt = e;

      // Check if user has dismissed install prompt before
      const dismissed = sessionStorage.getItem('install_prompt_dismissed');
      if (!dismissed) {
        // Show install prompt after 30 seconds
        setTimeout(() => {
          this.showInstallPrompt();
        }, 30000);
      }
    });

    // Detect if app was installed
    window.addEventListener('appinstalled', () => {
      console.log('[VersionManager] PWA installed');
      this.deferredInstallPrompt = null;

      // Hide install prompt if visible
      const prompt = document.getElementById('tractatus-install-prompt');
      if (prompt) {
        prompt.remove();
      }
    });
  }

  showInstallPrompt() {
    if (!this.deferredInstallPrompt) {
      return;
    }

    // Don't show if already installed or on iOS Safari (handles differently)
    if (window.matchMedia('(display-mode: standalone)').matches) {
      return;
    }

    const prompt = document.createElement('div');
    prompt.id = 'tractatus-install-prompt';
    prompt.className = 'fixed bottom-0 left-0 right-0 bg-gradient-to-r from-purple-600 to-blue-600 text-white px-4 py-3 shadow-lg z-50 transform transition-transform duration-300 translate-y-full';
    prompt.innerHTML = `
      <div class="max-w-7xl mx-auto flex items-center justify-between flex-wrap gap-4">
        <div class="flex items-start flex-1">
          <svg class="w-6 h-6 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"/>
          </svg>
          <div>
            <p class="font-semibold">Install Tractatus App</p>
            <p class="text-sm text-purple-100">
              Add to your home screen for quick access and offline support
            </p>
          </div>
        </div>
        <div class="flex gap-3">
          <button onclick="window.versionManager.dismissInstallPrompt()" class="text-white hover:text-purple-100 transition px-3">
            Not Now
          </button>
          <button onclick="window.versionManager.installApp()" class="bg-white text-purple-600 px-6 py-2 rounded-lg font-semibold hover:bg-purple-50 transition">
            Install
          </button>
        </div>
      </div>
    `;

    document.body.appendChild(prompt);

    // Animate in
    setTimeout(() => {
      prompt.classList.remove('translate-y-full');
    }, 100);
  }

  async installApp() {
    if (!this.deferredInstallPrompt) {
      return;
    }

    // Show the install prompt
    this.deferredInstallPrompt.prompt();

    // Wait for the user to respond to the prompt
    const { outcome } = await this.deferredInstallPrompt.userChoice;
    console.log(`[VersionManager] User response: ${outcome}`);

    // Clear the deferredInstallPrompt
    this.deferredInstallPrompt = null;

    // Hide the prompt
    this.dismissInstallPrompt();
  }

  dismissInstallPrompt() {
    const prompt = document.getElementById('tractatus-install-prompt');
    if (prompt) {
      prompt.classList.add('translate-y-full');
      setTimeout(() => {
        prompt.remove();
      }, 300);
    }

    // Remember dismissal for this session
    sessionStorage.setItem('install_prompt_dismissed', 'true');
  }
}

// Initialize version manager on page load
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', () => {
    window.versionManager = new VersionManager();
  });
} else {
  window.versionManager = new VersionManager();
}
