// SPDX-License-Identifier: GPL-3.0-or-later

/**
 * Format bytes to human-readable string
 */
export function formatBytes(bytes: number | undefined, decimals = 2): string {
  if (bytes === undefined || bytes === 0) return '0 B';

  const k = 1024;
  const dm = decimals < 0 ? 0 : decimals;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];

  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

/**
 * Format date to relative time string
 */
export function formatRelativeTime(date: string | Date | undefined): string {
  if (!date) return 'Never';
  
  const now = new Date();
  const then = new Date(date);
  const diffMs = now.getTime() - then.getTime();
  const diffSecs = Math.floor(diffMs / 1000);
  const diffMins = Math.floor(diffSecs / 60);
  const diffHours = Math.floor(diffMins / 60);
  const diffDays = Math.floor(diffHours / 24);

  if (diffSecs < 60) return 'Just now';
  if (diffMins < 60) return `${diffMins} minute${diffMins === 1 ? '' : 's'} ago`;
  if (diffHours < 24) return `${diffHours} hour${diffHours === 1 ? '' : 's'} ago`;
  if (diffDays < 7) return `${diffDays} day${diffDays === 1 ? '' : 's'} ago`;
  
  return then.toLocaleDateString();
}

/**
 * Format date to full date/time string
 */
export function formatDateTime(date: string | Date | undefined): string {
  if (!date) return '-';
  return new Date(date).toLocaleString();
}

/**
 * Format credits to display string
 */
export function formatCredits(credits: number | undefined): string {
  if (credits === undefined) return '0.00';
  return credits.toFixed(2);
}

/**
 * Calculate estimated monthly cost for storage.
 * Single-tier S3 pricing: 1 credit/TB/month = $9.99/credit.
 */
export function estimateMonthlyCost(bytes: number): number {
  const TB = 1024 * 1024 * 1024 * 1024;
  const creditPrice = 9.99;
  const totalTB = bytes / TB;
  return Math.ceil(totalTB) * creditPrice;
}

/**
 * Truncate string with ellipsis
 */
export function truncate(str: string, maxLength: number): string {
  if (str.length <= maxLength) return str;
  return str.slice(0, maxLength - 3) + '...';
}

/**
 * Truncate path from the middle
 */
export function truncatePath(path: string, maxLength: number): string {
  if (path.length <= maxLength) return path;
  
  const parts = path.split('/');
  if (parts.length <= 2) return truncate(path, maxLength);
  
  const first = parts[0] || '/';
  const last = parts[parts.length - 1];
  
  return `${first}/.../${last}`;
}

/**
 * Get status color class
 */
export function getStatusColor(status: string): string {
  switch (status.toLowerCase()) {
    case 'active':
    case 'completed':
    case 'success':
    case 'healthy':
    case 'connected':
      return 'text-green-600 dark:text-green-400';
    case 'pending':
    case 'running':
    case 'in_progress':
      return 'text-blue-600 dark:text-blue-400';
    case 'warning':
    case 'waiting':
      return 'text-yellow-600 dark:text-yellow-400';
    case 'error':
    case 'failed':
    case 'cancelled':
      return 'text-red-600 dark:text-red-400';
    default:
      return 'text-slate-600 dark:text-slate-400';
  }
}

/**
 * Get status badge classes
 */
export function getStatusBadge(status: string): string {
  const base = 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium';
  switch (status.toLowerCase()) {
    case 'active':
    case 'completed':
    case 'success':
    case 'healthy':
    case 'connected':
      return `${base} bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400`;
    case 'pending':
    case 'running':
    case 'in_progress':
      return `${base} bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400`;
    case 'warning':
    case 'waiting':
      return `${base} bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400`;
    case 'error':
    case 'failed':
    case 'cancelled':
      return `${base} bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400`;
    default:
      return `${base} bg-slate-100 text-slate-800 dark:bg-slate-700 dark:text-slate-300`;
  }
}

/**
 * Format duration from milliseconds
 */
export function formatDuration(ms: number | undefined): string {
  if (!ms || ms <= 0) return '-';
  const secs = Math.floor(ms / 1000);
  if (secs < 60) return `${secs}s`;
  const mins = Math.floor(secs / 60);
  const remainSecs = secs % 60;
  if (mins < 60) return `${mins}m ${remainSecs}s`;
  const hours = Math.floor(mins / 60);
  const remainMins = mins % 60;
  return `${hours}h ${remainMins}m`;
}

/**
 * Format a duration between two dates
 */
export function formatTimeBetween(start: string | Date | undefined, end: string | Date | undefined): string {
  if (!start) return '-';
  const startDate = new Date(start);
  const endDate = end ? new Date(end) : new Date();
  return formatDuration(endDate.getTime() - startDate.getTime());
}

/**
 * Format a schedule interval string to human readable
 */
export function formatScheduleInterval(interval: string): string {
  // Parse Go duration-style strings like "24h", "168h", "720h"
  const match = interval.match(/^(\d+)(s|m|h)$/);
  if (!match) return interval;
  const value = parseInt(match[1]);
  const unit = match[2];
  switch (unit) {
    case 's': return `${value} second${value !== 1 ? 's' : ''}`;
    case 'm': return `${value} minute${value !== 1 ? 's' : ''}`;
    case 'h':
      if (value >= 720) return `${Math.round(value / 720)} month${Math.round(value / 720) !== 1 ? 's' : ''}`;
      if (value >= 168) return `${Math.round(value / 168)} week${Math.round(value / 168) !== 1 ? 's' : ''}`;
      if (value >= 24) return `${Math.round(value / 24)} day${Math.round(value / 24) !== 1 ? 's' : ''}`;
      return `${value} hour${value !== 1 ? 's' : ''}`;
    default: return interval;
  }
}

/**
 * Capitalize first letter
 */
export function capitalize(str: string): string {
  if (!str) return '';
  return str.charAt(0).toUpperCase() + str.slice(1);
}
