/**
 * Pathway Viewer Alpine.js Component
 *
 * Provides reactive status management and polling for pathway predictions.
 * Handles status updates, change detection, and update notices.
 */

document.addEventListener('alpine:init', () => {
  /**
   * Pathway Viewer Component
   *
   * Usage:
   * <div x-data="pathwayViewer({
   *   status: 'running',
   *   modified: '2024-01-01T00:00:00Z',
   *   statusUrl: '/pathway/123?status=true'
   * })" x-init="init()">
   *   ...
   * </div>
   */
  Alpine.data('pathwayViewer', (config) => ({
    status: config.status,
    modified: config.modified,
    modifiedDate: null,
    statusUrl: config.statusUrl,
    emptyDueToThreshold: config.emptyDueToThreshold === "True",
    showUpdateNotice: false,
    showEmptyDueToThresholdNotice: false,
    emptyDueToThresholdMessage: 'The Pathway is empty due to the selected threshold. Please try a different threshold.',
    updateMessage: '',
    pollInterval: null,

    get statusTooltip() {
      const tooltips = {
        'completed': 'Pathway prediction completed.',
        'failed': 'Pathway prediction failed.',
        'running': 'Pathway prediction running.'
      };
      return tooltips[this.status] || '';
    },

    init() {
      this.modifiedDate = this.parseDate(this.modified);

      if (this.status === 'running') {
        this.startPolling();
      }

      if (this.emptyDueToThreshold) {
          this.showEmptyDueToThresholdNotice = true;
      }

    },

    startPolling() {
      if (this.pollInterval) {
        return;
      }
      this.pollInterval = setInterval(() => this.checkStatus(), 5000);
    },

    async checkStatus() {
      try {
        const response = await fetch(this.statusUrl);
        const data = await response.json();

        if (data.emptyDueToThreshold) {
          this.emptyDueToThreshold = true;
          this.showEmptyDueToThresholdNotice = true;
        }

        const nextModifiedDate = this.parseDate(data.modified);
        const modifiedChanged = this.hasNewerTimestamp(nextModifiedDate, this.modifiedDate);
        const statusChanged = data.status !== this.status;

        if ((modifiedChanged || statusChanged) && !this.emptyDueToThreshold) {
          this.showUpdateNotice = true;
          this.updateMessage = this.getUpdateMessage(data.status, modifiedChanged, statusChanged);
        }

        this.modified = data.modified;
        this.modifiedDate = nextModifiedDate;
        this.status = data.status;

        if (data.status !== 'running' && this.pollInterval) {
          clearInterval(this.pollInterval);
          this.pollInterval = null;
        }
      } catch (err) {
        console.error('Polling error:', err);
      }
    },

    getUpdateMessage(status, modifiedChanged, statusChanged) {
      // Prefer explicit status change messaging, otherwise fall back to modified change copy
      if (statusChanged) {
        if (status === 'completed') {
          return 'Prediction completed. Reload the page to see the updated Pathway.';
        }
        if (status === 'failed') {
          return 'Prediction failed. Reload the page to see the latest status.';
        }
      }

      let msg = 'Prediction ';

      if (status === 'running') {
        msg += 'is still running. But the Pathway was updated.';
      } else if (status === 'completed') {
        msg += 'is completed. Reload the page to see the updated Pathway.';
      } else if (status === 'failed') {
        msg += 'failed. Reload the page to see the current shape.';
      }

      return msg;
    },

    parseDate(dateString) {
      // Normalize "YYYY-MM-DD HH:mm:ss" into an ISO-compatible string to avoid locale issues
      if (!dateString) return null;
      return new Date(dateString.replace(' ', 'T'));
    },

    hasNewerTimestamp(nextDate, currentDate) {
      if (!nextDate) return false;
      if (!currentDate) return true;
      return nextDate.getTime() > currentDate.getTime();
    },

    reloadPage() {
      location.reload();
    }
  }));
});
