

let cachedCurrency: string | null = null;

if (typeof window !== 'undefined') {
  window.addEventListener('currencyChanged', ((e: CustomEvent) => {
    cachedCurrency = e.detail?.currency || null;
  }) as EventListener);
  
  
  window.addEventListener('storage', (e) => {
    if (e.key === 'currency') {
      cachedCurrency = e.newValue;
      window.dispatchEvent(new CustomEvent('currencyChanged', {
        detail: { currency: e.newValue }
      }));
    }
  });
}

export const getCurrencySymbol = (currencyCode: string): string => {
  try {
    
    const formatter = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: currencyCode,
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
    });
    
    const parts = formatter.formatToParts(0);
    const symbolPart = parts.find(part => part.type === 'currency');
    return symbolPart?.value || currencyCode;
  } catch {
    return currencyCode;
  }
};

export const formatCurrency = (
  amount: number | string,
  currency?: string
): string => {
  const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;
  
  if (isNaN(numAmount)) {
    return `0 ${currency || 'USD'}`;
  }
  
  
  let currencyToUse = currency;
  if (!currencyToUse && typeof window !== 'undefined') {
    try {
      if (cachedCurrency) {
        currencyToUse = cachedCurrency;
      } else {
        const storedCurrency = localStorage.getItem('currency');
        if (storedCurrency) {
          cachedCurrency = storedCurrency;
          currencyToUse = storedCurrency;
        }
      }
    } catch {
      // ignore storage access errors (private mode / blocked access)
    }
  }
  
  currencyToUse = currencyToUse || 'USD';
  
  
  const localeMap: Record<string, string> = {
    'USD': 'en-US',
    'EUR': 'de-DE',
    'GBP': 'en-GB',
    'JPY': 'ja-JP',
    'CNY': 'zh-CN',
    'KRW': 'ko-KR',
    'SGD': 'en-SG',
    'THB': 'th-TH',
    'AUD': 'en-AU',
    'CAD': 'en-CA',
  };
  
  const locale = localeMap[currencyToUse] || 'en-US';
  
  return new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currencyToUse,
    minimumFractionDigits: currencyToUse === 'JPY' ? 0 : 2,
    maximumFractionDigits: currencyToUse === 'JPY' ? 0 : 2,
  }).format(numAmount);
};

export const formatDateLocal = (date: Date): string => {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
};

export const parseDateLocal = (dateString: string): Date => {
  
  if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
    const [year, month, day] = dateString.split('-').map(Number);
    return new Date(year, month - 1, day);
  }
  
  const date = new Date(dateString);
  
  if (!dateString.includes('T') && !dateString.includes('Z') && !dateString.includes('+')) {
    const [year, month, day] = dateString.split('-').map(Number);
    return new Date(year, month - 1, day);
  }
  return date;
};

export const formatDate = (
  date: string | Date,
  format: 'short' | 'medium' | 'long' | 'full' = 'medium'
): string => {
  
  let dateObj: Date;
  if (typeof date === 'string') {
    dateObj = parseDateLocal(date);
  } else {
    dateObj = date;
  }
  
  if (isNaN(dateObj.getTime())) return 'Invalid Date';
  
  const formatOptions: Record<string, Intl.DateTimeFormatOptions> = {
    short: { year: 'numeric', month: 'numeric', day: 'numeric' },
    medium: { year: 'numeric', month: 'short', day: 'numeric' },
    long: { year: 'numeric', month: 'long', day: 'numeric' },
    full: { 
      year: 'numeric', 
      month: 'long', 
      day: 'numeric',
      weekday: 'long'
    },
  };
  
  return new Intl.DateTimeFormat('en-US', formatOptions[format]).format(dateObj);
};

export const formatDateTime = (
  date: string | Date,
  includeSeconds: boolean = false
): string => {
  const dateObj = typeof date === 'string' ? new Date(date) : date;
  
  if (isNaN(dateObj.getTime())) return 'Invalid Date';
  
  return new Intl.DateTimeFormat('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    ...(includeSeconds && { second: '2-digit' }),
  }).format(dateObj);
};

export const formatRelativeTime = (date: string | Date): string => {
  const dateObj = typeof date === 'string' ? new Date(date) : date;
  const now = new Date();
  const diffInSeconds = Math.floor((now.getTime() - dateObj.getTime()) / 1000);
  
  if (diffInSeconds < 0) return 'in the future';
  if (diffInSeconds < 60) return 'just now';
  if (diffInSeconds < 3600) {
    const minutes = Math.floor(diffInSeconds / 60);
    return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
  }
  if (diffInSeconds < 86400) {
    const hours = Math.floor(diffInSeconds / 3600);
    return `${hours} hour${hours > 1 ? 's' : ''} ago`;
  }
  if (diffInSeconds < 604800) {
    const days = Math.floor(diffInSeconds / 86400);
    return `${days} day${days > 1 ? 's' : ''} ago`;
  }
  
  return formatDate(dateObj, 'short');
};

export const formatNumber = (
  num: number | string,
  decimals: number = 0
): string => {
  const numValue = typeof num === 'string' ? parseFloat(num) : num;
  
  if (isNaN(numValue)) return '0';
  
  return new Intl.NumberFormat('en-US', {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  }).format(numValue);
};

export const formatPhoneNumber = (phone: string): string => {
  const cleaned = phone.replace(/\D/g, '');
  
  if (cleaned.length === 10) {
    return cleaned.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
  }
  
  if (cleaned.length === 11) {
    return cleaned.replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');
  }
  
  return phone;
};

export const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 Bytes';
  
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
};

export const truncateText = (
  text: string,
  maxLength: number,
  suffix: string = '...'
): string => {
  if (text.length <= maxLength) return text;
  return text.slice(0, maxLength - suffix.length) + suffix;
};

/**
 * Format working hours from 24-hour format to 12-hour format
 * @param startHour - Start hour in 24-hour format (0-23)
 * @param endHour - End hour in 24-hour format (0-23)
 * @returns Formatted string like "9:00 AM - 5:00 PM"
 */
export const formatWorkingHours = (startHour: number, endHour: number): string => {
  const formatHour = (hour: number): string => {
    if (hour === 0) return '12:00 AM';
    if (hour < 12) return `${hour}:00 AM`;
    if (hour === 12) return '12:00 PM';
    return `${hour - 12}:00 PM`;
  };

  return `${formatHour(startHour)} - ${formatHour(endHour)}`;
};

