/**
 * Input validators and formatters for phone numbers, SIDs, etc.
 */

/** Validate and format a phone number to E.164 */
export function toE164(phone: string): string {
  const cleaned = phone.replace(/[\s\-\(\)\.]/g, '');
  if (cleaned.startsWith('+')) return cleaned;
  if (cleaned.length === 10) return `+1${cleaned}`; // US default
  if (cleaned.length === 11 && cleaned.startsWith('1')) return `+${cleaned}`;
  return `+${cleaned}`;
}

/** Check if a string is a valid E.164 phone number */
export function isValidPhone(phone: string): boolean {
  return /^\+[1-9]\d{1,14}$/.test(toE164(phone));
}

/** Check if a string is a Twilio SID */
export function isSid(str: string, prefix?: string): boolean {
  if (prefix) return new RegExp(`^${prefix}[a-f0-9]{32}$`).test(str);
  return /^[A-Z]{2}[a-f0-9]{32}$/.test(str);
}

/** Format seconds to human-readable duration */
export function formatDuration(seconds: number): string {
  if (seconds < 60) return `${seconds}s`;
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  if (mins < 60) return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`;
  const hours = Math.floor(mins / 60);
  const remainMins = mins % 60;
  return `${hours}h ${remainMins}m`;
}

/** Format a date relative to now */
export function timeAgo(date: Date | string): string {
  const now = new Date();
  const then = typeof date === 'string' ? new Date(date) : date;
  const seconds = Math.floor((now.getTime() - then.getTime()) / 1000);

  if (seconds < 60) return 'just now';
  if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
  if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
  if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;
  return then.toLocaleDateString();
}

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

/** Map Twilio message status to display info */
export function messageStatusInfo(status: string): { label: string; color: 'green' | 'yellow' | 'red' | 'blue' | 'gray' } {
  const map: Record<string, { label: string; color: 'green' | 'yellow' | 'red' | 'blue' | 'gray' }> = {
    delivered: { label: 'Delivered', color: 'green' },
    sent: { label: 'Sent', color: 'blue' },
    queued: { label: 'Queued', color: 'yellow' },
    sending: { label: 'Sending', color: 'yellow' },
    accepted: { label: 'Accepted', color: 'blue' },
    receiving: { label: 'Receiving', color: 'blue' },
    received: { label: 'Received', color: 'green' },
    failed: { label: 'Failed', color: 'red' },
    undelivered: { label: 'Undelivered', color: 'red' },
    canceled: { label: 'Canceled', color: 'gray' },
    read: { label: 'Read', color: 'green' },
  };
  return map[status] || { label: status, color: 'gray' };
}

/** Map Twilio call status to display info */
export function callStatusInfo(status: string): { label: string; color: 'green' | 'yellow' | 'red' | 'blue' | 'gray' } {
  const map: Record<string, { label: string; color: 'green' | 'yellow' | 'red' | 'blue' | 'gray' }> = {
    completed: { label: 'Completed', color: 'green' },
    'in-progress': { label: 'In Progress', color: 'blue' },
    ringing: { label: 'Ringing', color: 'yellow' },
    queued: { label: 'Queued', color: 'yellow' },
    initiated: { label: 'Initiated', color: 'blue' },
    busy: { label: 'Busy', color: 'yellow' },
    'no-answer': { label: 'No Answer', color: 'red' },
    failed: { label: 'Failed', color: 'red' },
    canceled: { label: 'Canceled', color: 'gray' },
  };
  return map[status] || { label: status, color: 'gray' };
}
