/**
 * Date Utilities
 * All date functions work with UTC dates to avoid timezone issues
 */

/**
 * Parse a date string as UTC date (ignoring timezone)
 * This ensures dates like "2025-11-15" are always treated as November 15, 2025
 * regardless of the user's timezone
 * 
 * @param {string|Date} dateInput - Date string (YYYY-MM-DD) or Date object
 * @returns {Date} Date object in UTC
 */
export function parseUTCDate(dateInput) {
  if (!dateInput) return null;
  
  // If already a Date object, return it
  if (dateInput instanceof Date) {
    return dateInput;
  }
  
  // Parse YYYY-MM-DD string as UTC
  const [year, month, day] = dateInput.split('T')[0].split('-').map(Number);
  return new Date(Date.UTC(year, month - 1, day));
}

/**
 * Format a date for display
 * 
 * @param {string|Date} dateInput - Date string or Date object
 * @param {string} locale - Locale string (default: 'en-US')
 * @param {Object} options - Intl.DateTimeFormat options
 * @returns {string} Formatted date string
 */
export function formatDateForDisplay(dateInput, locale = 'en-US', options = {}) {
  if (!dateInput) return '';
  
  const date = parseUTCDate(dateInput);
  if (!date) return '';
  
  const defaultOptions = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    timeZone: 'UTC',
    ...options
  };
  
  return date.toLocaleDateString(locale, defaultOptions);
}

/**
 * Format a date for HTML input type="date"
 * Returns YYYY-MM-DD format
 * 
 * @param {string|Date} dateInput - Date string or Date object
 * @returns {string} Date in YYYY-MM-DD format
 */
export function formatDateForInput(dateInput) {
  if (!dateInput) return '';
  
  const date = parseUTCDate(dateInput);
  if (!date) return '';
  
  const year = date.getUTCFullYear();
  const month = String(date.getUTCMonth() + 1).padStart(2, '0');
  const day = String(date.getUTCDate()).padStart(2, '0');
  
  return `${year}-${month}-${day}`;
}

/**
 * Format a date for HTML input type="datetime-local"
 * Returns YYYY-MM-DDTHH:MM format
 *
 * @param {string|Date} dateInput - Date string or Date object
 * @returns {string} Date in YYYY-MM-DDTHH:MM format
 */
export function formatDateTimeForInput(dateInput) {
  if (!dateInput) return '';

  const date = new Date(dateInput);
  if (isNaN(date.getTime())) return '';

  const year = date.getUTCFullYear();
  const month = String(date.getUTCMonth() + 1).padStart(2, '0');
  const day = String(date.getUTCDate()).padStart(2, '0');
  const hours = String(date.getUTCHours()).padStart(2, '0');
  const minutes = String(date.getUTCMinutes()).padStart(2, '0');

  return `${year}-${month}-${day}T${hours}:${minutes}`;
}

/**
 * Format a datetime string for display (preserves time component)
 * Use this for datetime fields — formatDateForDisplay strips the time via parseUTCDate.
 *
 * @param {string|Date} dateInput - ISO datetime string or Date object
 * @param {string} locale - Locale string (default: 'fr-FR')
 * @param {Object} options - Intl.DateTimeFormat options
 * @returns {string} Formatted datetime string
 */
export function formatDateTimeForDisplay(dateInput, locale = 'fr-FR', options = {}) {
  if (!dateInput) return '';

  const date = new Date(dateInput);
  if (isNaN(date.getTime())) return '';

  const defaultOptions = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    timeZone: 'UTC',
    ...options
  };

  return date.toLocaleDateString(locale, defaultOptions);
}

/**
 * Format a date for short display (e.g., "Nov 15, 2025")
 * 
 * @param {string|Date} dateInput - Date string or Date object
 * @param {string} locale - Locale string (default: 'en-US')
 * @returns {string} Formatted date string
 */
export function formatDateShort(dateInput, locale = 'en-US') {
  return formatDateForDisplay(dateInput, locale, {
    year: 'numeric',
    month: 'short',
    day: 'numeric'
  });
}

/**
 * Calculate days between two dates
 * 
 * @param {string|Date} date1 - First date
 * @param {string|Date} date2 - Second date
 * @returns {number} Number of days between dates (can be negative)
 */
export function getDaysBetween(date1, date2) {
  const d1 = parseUTCDate(date1);
  const d2 = parseUTCDate(date2);
  
  if (!d1 || !d2) return 0;
  
  // Reset both dates to midnight UTC to avoid any time component issues
  d1.setUTCHours(0, 0, 0, 0);
  d2.setUTCHours(0, 0, 0, 0);
  
  const diffTime = d2.getTime() - d1.getTime();
  const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24));
  
  return diffDays;
}

/**
 * Add days to a date
 * 
 * @param {string|Date} dateInput - Date to add days to
 * @param {number} days - Number of days to add (can be negative)
 * @returns {Date} New date with days added
 */
export function addDays(dateInput, days) {
  const date = parseUTCDate(dateInput);
  if (!date) return null;
  
  const newDate = new Date(date);
  newDate.setUTCDate(newDate.getUTCDate() + days);
  
  return newDate;
}

/**
 * Subtract days from a date
 * 
 * @param {string|Date} dateInput - Date to subtract days from
 * @param {number} days - Number of days to subtract
 * @returns {Date} New date with days subtracted
 */
export function subtractDays(dateInput, days) {
  return addDays(dateInput, -days);
}

/**
 * Check if a date is overdue (before today)
 * 
 * @param {string|Date} dueDate - Due date to check
 * @param {string|Date} today - Today's date (default: current date)
 * @returns {boolean} True if overdue
 */
export function isOverdue(dueDate, today = null) {
  const due = parseUTCDate(dueDate);
  if (!due) return false;
  
  const todayDate = today ? parseUTCDate(today) : getTodayUTC();
  
  return due < todayDate;
}

/**
 * Get today's date in UTC (at midnight)
 * 
 * @returns {Date} Today's date in UTC
 */
export function getTodayUTC() {
  const now = new Date();
  return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
}

/**
 * Get today's date as YYYY-MM-DD string
 * 
 * @returns {string} Today's date in YYYY-MM-DD format
 */
export function getTodayString() {
  return formatDateForInput(getTodayUTC());
}

/**
 * Compare two dates (ignoring time)
 * 
 * @param {string|Date} date1 - First date
 * @param {string|Date} date2 - Second date
 * @returns {number} -1 if date1 < date2, 0 if equal, 1 if date1 > date2
 */
export function compareDates(date1, date2) {
  const d1 = parseUTCDate(date1);
  const d2 = parseUTCDate(date2);
  
  if (!d1 || !d2) return 0;
  
  if (d1 < d2) return -1;
  if (d1 > d2) return 1;
  return 0;
}

