/**
 * Formatting utilities for various data types
 */

// Number formatting
export const formatNumber = (
  value: number,
  options: Intl.NumberFormatOptions = {}
): string => {
  if (typeof value !== 'number' || isNaN(value)) {
    return '0';
  }

  const defaultOptions: Intl.NumberFormatOptions = {
    minimumFractionDigits: 0,
    maximumFractionDigits: 2,
  };

  return new Intl.NumberFormat('es-ES', { ...defaultOptions, ...options }).format(value);
};

// Currency formatting
export const formatCurrency = (
  amount: number,
  currency: string = 'EUR',
  locale: string = 'es-ES'
): string => {
  if (typeof amount !== 'number' || isNaN(amount)) {
    return new Intl.NumberFormat(locale, {
      style: 'currency',
      currency,
    }).format(0);
  }

  return new Intl.NumberFormat(locale, {
    style: 'currency',
    currency,
  }).format(amount);
};

// Percentage formatting
export const formatPercentage = (
  value: number,
  decimals: number = 1,
  locale: string = 'es-ES'
): string => {
  if (typeof value !== 'number' || isNaN(value)) {
    return '0%';
  }

  return new Intl.NumberFormat(locale, {
    style: 'percent',
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  }).format(value / 100);
};

// Compact number formatting (1K, 1M, etc.)
export const formatCompactNumber = (
  value: number,
  locale: string = 'es-ES'
): string => {
  if (typeof value !== 'number' || isNaN(value)) {
    return '0';
  }

  return new Intl.NumberFormat(locale, {
    notation: 'compact',
    compactDisplay: 'short',
  }).format(value);
};

// Decimal formatting with specific precision
export const formatDecimal = (
  value: number,
  decimals: number = 2,
  locale: string = 'es-ES'
): string => {
  if (typeof value !== 'number' || isNaN(value)) {
    return '0';
  }

  return new Intl.NumberFormat(locale, {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  }).format(value);
};

// File size formatting
export const formatFileSize = (bytes: number): string => {
  if (typeof bytes !== 'number' || isNaN(bytes)) {
    return '0 B';
  }

  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  if (bytes === 0) return '0 B';

  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  const size = bytes / Math.pow(1024, i);

  return `${formatDecimal(size, i === 0 ? 0 : 1)} ${sizes[i]}`;
};

// Duration formatting (milliseconds to human readable)
export const formatDuration = (milliseconds: number): string => {
  if (typeof milliseconds !== 'number' || isNaN(milliseconds) || milliseconds < 0) {
    return '0s';
  }

  const seconds = Math.floor(milliseconds / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (days > 0) {
    return `${days}d ${hours % 24}h`;
  } else if (hours > 0) {
    return `${hours}h ${minutes % 60}m`;
  } else if (minutes > 0) {
    return `${minutes}m ${seconds % 60}s`;
  } else {
    return `${seconds}s`;
  }
};

// Short duration formatting (for performance metrics)
export const formatShortDuration = (milliseconds: number): string => {
  if (typeof milliseconds !== 'number' || isNaN(milliseconds)) {
    return '0ms';
  }

  if (milliseconds < 1000) {
    return `${Math.round(milliseconds)}ms`;
  }

  const seconds = milliseconds / 1000;
  if (seconds < 60) {
    return `${formatDecimal(seconds, 1)}s`;
  }

  const minutes = seconds / 60;
  return `${formatDecimal(minutes, 1)}m`;
};

// Text formatting
export const truncateText = (
  text: string,
  maxLength: number,
  suffix: string = '...'
): string => {
  if (!text || typeof text !== 'string') {
    return '';
  }

  if (text.length <= maxLength) {
    return text;
  }

  return text.slice(0, maxLength - suffix.length) + suffix;
};

// Capitalize first letter
export const capitalize = (text: string): string => {
  if (!text || typeof text !== 'string') {
    return '';
  }

  return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
};

// Title case formatting
export const titleCase = (text: string): string => {
  if (!text || typeof text !== 'string') {
    return '';
  }

  return text
    .toLowerCase()
    .split(' ')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
};

// Kebab case to title case
export const kebabToTitle = (text: string): string => {
  if (!text || typeof text !== 'string') {
    return '';
  }

  return text
    .split('-')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
};

// Snake case to title case
export const snakeToTitle = (text: string): string => {
  if (!text || typeof text !== 'string') {
    return '';
  }

  return text
    .split('_')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
};

// Camel case to title case
export const camelToTitle = (text: string): string => {
  if (!text || typeof text !== 'string') {
    return '';
  }

  return text
    .replace(/([A-Z])/g, ' $1')
    .replace(/^./, str => str.toUpperCase())
    .trim();
};

// Phone number formatting
export const formatPhoneNumber = (phone: string): string => {
  if (!phone || typeof phone !== 'string') {
    return '';
  }

  // Remove all non-digit characters
  const digits = phone.replace(/\D/g, '');

  // Spanish phone number format
  if (digits.length === 9) {
    return `${digits.slice(0, 3)} ${digits.slice(3, 6)} ${digits.slice(6)}`;
  }

  // International format
  if (digits.length === 11 && digits.startsWith('34')) {
    return `+34 ${digits.slice(2, 5)} ${digits.slice(5, 8)} ${digits.slice(8)}`;
  }

  // Return original if doesn't match expected formats
  return phone;
};

// Unit of measure formatting
export const formatUnit = (value: number, unit: string): string => {
  if (typeof value !== 'number' || isNaN(value)) {
    return `0 ${unit}`;
  }

  const formattedValue = value % 1 === 0 ? value.toString() : formatDecimal(value);
  return `${formattedValue} ${unit}`;
};

// Weight formatting with unit conversion
export const formatWeight = (grams: number): string => {
  if (typeof grams !== 'number' || isNaN(grams)) {
    return '0 g';
  }

  if (grams >= 1000) {
    const kg = grams / 1000;
    return `${formatDecimal(kg)} kg`;
  }

  return `${formatDecimal(grams, 0)} g`;
};

// Volume formatting with unit conversion
export const formatVolume = (milliliters: number): string => {
  if (typeof milliliters !== 'number' || isNaN(milliliters)) {
    return '0 ml';
  }

  if (milliliters >= 1000) {
    const liters = milliliters / 1000;
    return `${formatDecimal(liters)} l`;
  }

  return `${formatDecimal(milliliters, 0)} ml`;
};

// Temperature formatting
export const formatTemperature = (
  celsius: number,
  unit: 'C' | 'F' = 'C'
): string => {
  if (typeof celsius !== 'number' || isNaN(celsius)) {
    return `0°${unit}`;
  }

  if (unit === 'F') {
    const fahrenheit = (celsius * 9/5) + 32;
    return `${formatDecimal(fahrenheit, 0)}°F`;
  }

  return `${formatDecimal(celsius, 0)}°C`;
};

// List formatting (join with commas and "and")
export const formatList = (
  items: string[],
  conjunction: string = 'y'
): string => {
  if (!Array.isArray(items) || items.length === 0) {
    return '';
  }

  if (items.length === 1) {
    return items[0];
  }

  if (items.length === 2) {
    return `${items[0]} ${conjunction} ${items[1]}`;
  }

  const lastItem = items[items.length - 1];
  const otherItems = items.slice(0, -1);
  return `${otherItems.join(', ')} ${conjunction} ${lastItem}`;
};

// Address formatting
export const formatAddress = (address: {
  street?: string;
  city?: string;
  postal_code?: string;
  country?: string;
}): string => {
  const parts = [];

  if (address.street) parts.push(address.street);
  if (address.postal_code && address.city) {
    parts.push(`${address.postal_code} ${address.city}`);
  } else if (address.city) {
    parts.push(address.city);
  } else if (address.postal_code) {
    parts.push(address.postal_code);
  }
  if (address.country) parts.push(address.country);

  return parts.join(', ');
};

// HTML stripping (for displaying rich text as plain text)
export const stripHtml = (html: string): string => {
  if (!html || typeof html !== 'string') {
    return '';
  }

  // Create a temporary div element to strip HTML tags
  const tmp = document.createElement('div');
  tmp.innerHTML = html;
  return tmp.textContent || tmp.innerText || '';
};

// URL slug generation
export const slugify = (text: string): string => {
  if (!text || typeof text !== 'string') {
    return '';
  }

  return text
    .toLowerCase()
    .replace(/[^\w ]+/g, '')
    .replace(/ +/g, '-');
};

// Name formatting (last name, first name)
export const formatName = (
  firstName: string,
  lastName: string,
  format: 'first_last' | 'last_first' | 'initials' = 'first_last'
): string => {
  const first = firstName?.trim() || '';
  const last = lastName?.trim() || '';

  if (!first && !last) return '';
  if (!first) return last;
  if (!last) return first;

  switch (format) {
    case 'last_first':
      return `${last}, ${first}`;
    case 'initials':
      return `${first.charAt(0)}.${last.charAt(0)}.`;
    case 'first_last':
    default:
      return `${first} ${last}`;
  }
};