(function () {
  window.PrimeBridge = window.PrimeBridge || {};

  /**
   * PrimeBridge.time — Time and date utility functions.
   *
   * Provides helpers for formatting timestamps, computing relative time
   * strings, and working with durations.
   *
   * @namespace PrimeBridge.time
   */
  PrimeBridge.time = {
    /**
     * timeAgo — Returns a human-readable relative time string.
     *
     * Examples: "just now", "2m ago", "1h ago", "3d ago"
     *
     * @param {number|string|Date} timestamp — A Unix timestamp (ms), ISO string, or Date object.
     * @returns {string} Relative time description.
     */
    timeAgo: function (timestamp) {
      var now = Date.now();
      var then = this._parseTimestamp(timestamp);
      if (then === null) return '';

      var diff = now - then;
      var seconds = Math.floor(diff / 1000);

      if (seconds < 10) return 'just now';
      if (seconds < 60) return seconds + 's ago';

      var minutes = Math.floor(seconds / 60);
      if (minutes < 60) return minutes + 'm ago';

      var hours = Math.floor(minutes / 60);
      if (hours < 24) return hours + 'h ago';

      var days = Math.floor(hours / 24);
      if (days < 30) return days + 'd ago';

      var months = Math.floor(days / 30);
      if (months < 12) return months + 'mo ago';

      var years = Math.floor(months / 12);
      return years + 'y ago';
    },

    /**
     * formatTimestamp — Formats a date as a localized time string.
     *
     * Defaults to "h:mm A" (12-hour) style via toLocaleTimeString.
     *
     * @param {number|string|Date} date — A Unix timestamp (ms), ISO string, or Date object.
     * @param {Object} [options] — Intl.DateTimeFormat options to override defaults.
     * @returns {string} Formatted time string, e.g. "12:34 PM".
     */
    formatTimestamp: function (date, options) {
      var d = this._toDate(date);
      if (d === null) return '';

      var opts = options || {
        hour: 'numeric',
        minute: '2-digit',
        hour12: true
      };

      return d.toLocaleTimeString(undefined, opts);
    },

    /**
     * formatDuration — Formats a duration in seconds to a human-readable string.
     *
     * Examples: "5m 23s", "2h 15m", "1d 4h"
     *
     * @param {number} seconds — Total duration in seconds.
     * @returns {string} Formatted duration string.
     */
    formatDuration: function (seconds) {
      if (typeof seconds !== 'number' || isNaN(seconds) || seconds < 0) return '0s';

      var total = Math.floor(seconds);
      var parts = [];

      var days = Math.floor(total / 86400);
      if (days > 0) {
        parts.push(days + 'd');
        total = total % 86400;
      }

      var hours = Math.floor(total / 3600);
      if (hours > 0) {
        parts.push(hours + 'h');
        total = total % 3600;
      }

      var minutes = Math.floor(total / 60);
      if (minutes > 0) {
        parts.push(minutes + 'm');
        total = total % 60;
      }

      if (total > 0 || parts.length === 0) {
        parts.push(total + 's');
      }

      return parts.join(' ');
    },

    /**
     * now — Returns the current timestamp in milliseconds.
     *
     * @returns {number} Current Unix timestamp (ms).
     */
    now: function () {
      return Date.now();
    },

    /**
     * relativeTime — Like timeAgo but with more precision.
     *
     * Returns the most precise non-zero unit with explicit labeling.
     * Examples: "2 minutes ago", "1 hour ago", "3 days ago"
     *
     * @param {number|string|Date} timestamp — A Unix timestamp (ms), ISO string, or Date object.
     * @returns {string} Precise relative time description.
     */
    relativeTime: function (timestamp) {
      var now = Date.now();
      var then = this._parseTimestamp(timestamp);
      if (then === null) return '';

      var diff = now - then;
      var seconds = Math.floor(diff / 1000);

      if (seconds < 10) return 'just now';

      var minutes = Math.floor(seconds / 60);
      if (minutes < 60) {
        var label = minutes === 1 ? 'minute' : 'minutes';
        return minutes + ' ' + label + ' ago';
      }

      var hours = Math.floor(minutes / 60);
      if (hours < 24) {
        var label = hours === 1 ? 'hour' : 'hours';
        return hours + ' ' + label + ' ago';
      }

      var days = Math.floor(hours / 24);
      if (days < 30) {
        var label = days === 1 ? 'day' : 'days';
        return days + ' ' + label + ' ago';
      }

      var months = Math.floor(days / 30);
      if (months < 12) {
        var label = months === 1 ? 'month' : 'months';
        return months + ' ' + label + ' ago';
      }

      var years = Math.floor(months / 12);
      var label = years === 1 ? 'year' : 'years';
      return years + ' ' + label + ' ago';
    },

    /* ── Internal Helpers ────────────────────────────────────────── */

    /**
     * _parseTimestamp — Converts various timestamp formats to a Unix ms number.
     *
     * @private
     * @param {number|string|Date} ts — Input timestamp.
     * @returns {number|null} Unix timestamp in milliseconds, or null on failure.
     */
    _parseTimestamp: function (ts) {
      if (ts === null || ts === undefined) return null;

      if (ts instanceof Date) return ts.getTime();

      if (typeof ts === 'number') return ts;

      if (typeof ts === 'string') {
        var parsed = Date.parse(ts);
        return isNaN(parsed) ? null : parsed;
      }

      return null;
    },

    /**
     * _toDate — Converts various timestamp formats to a Date object.
     *
     * @private
     * @param {number|string|Date} d — Input date/timestamp.
     * @returns {Date|null} A Date object, or null on failure.
     */
    _toDate: function (d) {
      if (d instanceof Date) return d;

      var ms = this._parseTimestamp(d);
      return ms !== null ? new Date(ms) : null;
    }
  };
})();
