/**
 * Timezone Utilities for American Eastern Time (EST/EDT)
 *
 * All sports data and user-facing times should be in Eastern Time
 * to match US sports schedules.
 *
 * EST = UTC-5 (November - March)
 * EDT = UTC-4 (March - November, Daylight Saving Time)
 */

/**
 * Get the current offset from UTC for America/New_York timezone.
 * Returns -5 for EST, -4 for EDT.
 */
export function getEasternOffset(): number {
  // Use Intl API to get the actual current offset
  const now = new Date();
  const formatter = new Intl.DateTimeFormat('en-US', {
    timeZone: 'America/New_York',
    timeZoneName: 'short'
  });

  const parts = formatter.formatToParts(now);
  const tzName = parts.find(p => p.type === 'timeZoneName')?.value || 'EST';

  // EDT = UTC-4, EST = UTC-5
  return tzName.includes('DT') || tzName.includes('Daylight') ? -4 : -5;
}

/**
 * Get current date/time in Eastern timezone.
 */
export function getNowEastern(): Date {
  const now = new Date();
  const offset = getEasternOffset();
  // Convert UTC to Eastern by adding the offset
  return new Date(now.getTime() + (offset * 60 * 60 * 1000) + (now.getTimezoneOffset() * 60 * 1000));
}

/**
 * Get today's date string (YYYY-MM-DD) in Eastern timezone.
 * This is the correct "today" for US sports.
 */
export function getTodayEastern(): string {
  // Use Intl to format in America/New_York timezone
  const now = new Date();
  const formatter = new Intl.DateTimeFormat('en-CA', {
    timeZone: 'America/New_York',
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  });
  return formatter.format(now); // Returns YYYY-MM-DD format
}

/**
 * Get the UTC date range that corresponds to a given Eastern date.
 * For example, Jan 29 EST spans:
 * - Start: Jan 29 05:00:00 UTC (midnight EST) or 04:00:00 UTC (midnight EDT)
 * - End: Jan 30 04:59:59 UTC (11:59 PM EST) or 03:59:59 UTC (11:59 PM EDT)
 */
export function getEasternDayRangeUTC(dateISO: string): { start: Date; end: Date } {
  const d = String(dateISO).slice(0, 10);
  const offset = getEasternOffset();
  const offsetMs = Math.abs(offset) * 60 * 60 * 1000;

  // Midnight Eastern = offset hours into UTC
  const start = new Date(`${d}T00:00:00.000Z`);
  start.setTime(start.getTime() + offsetMs);

  // 23:59:59 Eastern = offset hours into next UTC day
  const end = new Date(`${d}T23:59:59.999Z`);
  end.setTime(end.getTime() + offsetMs);

  return { start, end };
}

/**
 * Format a date for display in Eastern timezone.
 */
export function formatEastern(date: Date, options?: Intl.DateTimeFormatOptions): string {
  const defaultOptions: Intl.DateTimeFormatOptions = {
    timeZone: 'America/New_York',
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
    hour12: true
  };

  return new Intl.DateTimeFormat('en-US', { ...defaultOptions, ...options }).format(date);
}

/**
 * Format a date as just the date portion in Eastern timezone.
 */
export function formatDateEastern(date: Date): string {
  return new Intl.DateTimeFormat('en-US', {
    timeZone: 'America/New_York',
    weekday: 'short',
    month: 'short',
    day: 'numeric'
  }).format(date);
}

/**
 * Format a date as just the time portion in Eastern timezone.
 */
export function formatTimeEastern(date: Date): string {
  return new Intl.DateTimeFormat('en-US', {
    timeZone: 'America/New_York',
    hour: 'numeric',
    minute: '2-digit',
    hour12: true
  }).format(date);
}

/**
 * Get the Eastern timezone abbreviation (EST or EDT).
 */
export function getEasternTimezoneAbbr(): string {
  const now = new Date();
  const formatter = new Intl.DateTimeFormat('en-US', {
    timeZone: 'America/New_York',
    timeZoneName: 'short'
  });

  const parts = formatter.formatToParts(now);
  return parts.find(p => p.type === 'timeZoneName')?.value || 'ET';
}

/**
 * Parse a date string and return it as if it were in Eastern timezone.
 * Useful for user input that should be interpreted as Eastern time.
 */
export function parseAsEastern(dateStr: string): Date {
  // If it's just a date (YYYY-MM-DD), treat it as midnight Eastern
  if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
    const offset = getEasternOffset();
    const utcMidnight = new Date(`${dateStr}T00:00:00.000Z`);
    // Add offset to get the UTC equivalent of midnight Eastern
    utcMidnight.setTime(utcMidnight.getTime() + (Math.abs(offset) * 60 * 60 * 1000));
    return utcMidnight;
  }

  // Otherwise parse normally
  return new Date(dateStr);
}

/**
 * Check if a game time has passed (in Eastern timezone).
 */
export function hasGameStarted(gameTime: Date): boolean {
  return new Date() > gameTime;
}

/**
 * Get relative time description (e.g., "in 2 hours", "started 30 min ago").
 */
export function getRelativeTime(date: Date): string {
  const now = new Date();
  const diff = date.getTime() - now.getTime();
  const absDiff = Math.abs(diff);

  const minutes = Math.floor(absDiff / (1000 * 60));
  const hours = Math.floor(absDiff / (1000 * 60 * 60));
  const days = Math.floor(absDiff / (1000 * 60 * 60 * 24));

  if (diff > 0) {
    // Future
    if (days > 0) return `in ${days}d`;
    if (hours > 0) return `in ${hours}h`;
    if (minutes > 0) return `in ${minutes}m`;
    return 'starting now';
  } else {
    // Past
    if (days > 0) return `${days}d ago`;
    if (hours > 0) return `${hours}h ago`;
    if (minutes > 0) return `${minutes}m ago`;
    return 'just now';
  }
}
