import React from 'react';
import { useSyncExternalStore } from 'react';
import { subscribe, getSnapshot } from './TimeTicker';

interface TimeAgoProps {
  time?: string | null | Date;
  format?: 'short' | 'long';
  showAgo?: boolean;
}

// Returns a compact label for a time difference (UTC millisecond inputs).
function formatRelative(nowMs: number, timeMs: number, fmt: 'short' | 'long' = 'short', showAgo = true): string {
  const diffSec = Math.max(0, Math.floor((nowMs - timeMs) / 1000));

  const units = [
    { threshold: 60, divisor: 1, short: 's', long: 'second' },
    { threshold: 60 * 60, divisor: 60, short: 'm', long: 'minute' },
    { threshold: 60 * 60 * 24, divisor: 60 * 60, short: 'h', long: 'hour' },
    { threshold: 60 * 60 * 24 * 7, divisor: 60 * 60 * 24, short: 'd', long: 'day' },
    { threshold: 60 * 60 * 24 * 30, divisor: 60 * 60 * 24 * 7, short: 'w', long: 'week' },
    // months: fallback bucket
    { threshold: Infinity, divisor: 60 * 60 * 24 * 30, short: 'mo', long: 'month' },
  ];

  const plural = (n: number, singular: string) => (n === 1 ? `${n} ${singular}` : `${n} ${singular}s`);

  // find first matching unit
  for (const u of units) {
    if (diffSec < u.threshold) {
      if (fmt === 'short') {
        if (u.short === 'mo') {
          // for months, compute from days to ensure at least 1 month
          const months = Math.max(1, Math.floor(diffSec / u.divisor));
          return `${months}${u.short}${showAgo ? ' ago' : ''}`;
        }
        const value = Math.floor(diffSec / u.divisor);
        return `${value}${u.short}${showAgo ? ' ago' : ''}`;
      }

      // long format
      if (diffSec < 1) return 'just now';
      if (u.long === 'month') {
        const months = Math.max(1, Math.floor(diffSec / u.divisor));
        return `${plural(months, u.long)}${showAgo ? ' ago' : ''}`;
      }
      const value = Math.floor(diffSec / u.divisor);
      return `${plural(value, u.long)}${showAgo ? ' ago' : ''}`;
    }
  }

  return 'just now';
}

// TimeAgo subscribes to a single shared ticker (via useSyncExternalStore) so
// many instances update efficiently without per-component timers.
const TimeAgo: React.FC<TimeAgoProps> = ({ time, format = 'short', showAgo = true }) => {
  if (!time) return <>-</>;

  const now = useSyncExternalStore(subscribe, getSnapshot);

  const timeMs = typeof time === 'string'
    ? Date.parse(time)
    : (time instanceof Date ? time.getTime() : NaN);

  if (!timeMs || Number.isNaN(timeMs)) return <>-</>;

  const label = formatRelative(now, timeMs, format, showAgo);

  return <span title={new Date(timeMs).toLocaleString()}>{label}</span>;
};

export default TimeAgo;
