/**
 * User Management Utility Functions
 *
 * Helper functions for user management operations including:
 * - Status determination
 * - Date formatting
 * - Data transformations
 * - Text utilities
 *
 * @module utils/user-management
 */

import type { AccountStatus, UserRole } from '@/lib/types/user-management.types';
import { STATUS_COLORS, NOTE_CATEGORIES } from '@/lib/constants/user-management.constants';

// ============================================
// STATUS UTILITIES
// ============================================

/**
 * Determine account status from user flags
 *
 * @param user - User object with status fields
 * @returns Account status
 *
 * @example
 * const status = determineAccountStatus(user);
 * // Returns: 'active' | 'suspended' | 'locked' | 'inactive'
 */
export function determineAccountStatus(user: {
  isActive: boolean;
  isSuspended: boolean;
  lockedUntil: Date | null;
}): AccountStatus {
  if (user.isSuspended) return 'suspended';
  if (user.lockedUntil && new Date(user.lockedUntil) > new Date()) return 'locked';
  if (user.isActive) return 'active';
  return 'inactive';
}

/**
 * Get color classes for account status
 *
 * @param status - Account status
 * @returns Tailwind CSS classes
 */
export function getStatusColors(status: AccountStatus) {
  return STATUS_COLORS[status];
}

/**
 * Get status label with icon
 *
 * @param status - Account status
 * @returns Formatted label
 */
export function getStatusLabel(status: AccountStatus): string {
  const colors = STATUS_COLORS[status];
  return `${colors.icon} ${status.charAt(0).toUpperCase() + status.slice(1)}`;
}

// ============================================
// DATE UTILITIES
// ============================================

/**
 * Format date relative to now (e.g., "2 hours ago", "3 days ago")
 *
 * @param date - Date to format
 * @returns Relative time string
 */
export function formatRelativeTime(date: Date | string | null): string {
  if (!date) return 'Never';

  const now = new Date();
  const then = new Date(date);
  const diff = now.getTime() - then.getTime();

  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);
  const weeks = Math.floor(days / 7);
  const months = Math.floor(days / 30);

  if (seconds < 60) return 'Just now';
  if (minutes < 60) return `${minutes}m ago`;
  if (hours < 24) return `${hours}h ago`;
  if (days < 7) return `${days}d ago`;
  if (weeks < 4) return `${weeks}w ago`;
  return `${months}mo ago`;
}

/**
 * Format date for display
 *
 * @param date - Date to format
 * @param format - Format style
 * @returns Formatted date string
 */
export function formatDate(
  date: Date | string | null,
  format: 'short' | 'long' | 'iso' = 'short'
): string {
  if (!date) return '-';

  const d = new Date(date);

  if (format === 'iso') {
    return d.toISOString();
  }

  if (format === 'long') {
    return d.toLocaleDateString('en-US', {
      weekday: 'long',
      year: 'numeric',
      month: 'long',
      day: 'numeric',
    });
  }

  return d.toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
  });
}

// ============================================
// TEXT UTILITIES
// ============================================

/**
 * Truncate text to specified length
 *
 * @param text - Text to truncate
 * @param maxLength - Maximum length
 * @returns Truncated text with ellipsis
 */
export function truncateText(text: string, maxLength: number = 50): string {
  if (text.length <= maxLength) return text;
  return text.slice(0, maxLength) + '...';
}

/**
 * Get initials from name
 *
 * @param name - Full name
 * @returns Initials (max 2 characters)
 */
export function getInitials(name: string): string {
  if (!name) return '?';

  const parts = name.trim().split(' ');
  if (parts.length === 1) return parts[0].charAt(0).toUpperCase();

  return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
}

/**
 * Pluralize word based on count
 *
 * @param count - Number of items
 * @param singular - Singular form
 * @param plural - Plural form (optional, defaults to singular + 's')
 * @returns Pluralized string with count
 */
export function pluralize(
  count: number,
  singular: string,
  plural?: string
): string {
  const word = count === 1 ? singular : plural || singular + 's';
  return `${count} ${word}`;
}

// ============================================
// ROLE UTILITIES
// ============================================

/**
 * Get role display color
 *
 * @param role - User role
 * @returns Tailwind color class
 */
export function getRoleColor(role: UserRole): string {
  const colors: Record<UserRole, string> = {
    CUSTOMER: 'blue',
    STAFF: 'purple',
    ADMIN: 'red',
    SUPER_ADMIN: 'orange',
  };

  return colors[role] || 'gray';
}

/**
 * Get role badge classes
 *
 * @param role - User role
 * @returns Tailwind CSS classes
 */
export function getRoleBadgeClasses(role: UserRole): string {
  const color = getRoleColor(role);

  // Static color variants mapping for Tailwind JIT compiler
  const colorVariants: Record<string, string> = {
    blue: 'bg-blue-50 text-blue-700 border-blue-200',
    purple: 'bg-purple-50 text-purple-700 border-purple-200',
    emerald: 'bg-emerald-50 text-emerald-700 border-emerald-200',
    amber: 'bg-amber-50 text-amber-700 border-amber-200',
    gray: 'bg-gray-50 text-gray-700 border-gray-200',
    green: 'bg-green-50 text-green-700 border-green-200',
    orange: 'bg-orange-50 text-orange-700 border-orange-200',
    red: 'bg-red-50 text-red-700 border-red-200',
    yellow: 'bg-yellow-50 text-yellow-700 border-yellow-200',
    pink: 'bg-pink-50 text-pink-700 border-pink-200',
    rose: 'bg-rose-50 text-rose-700 border-rose-200',
    slate: 'bg-slate-50 text-slate-700 border-slate-200',
  };

  return colorVariants[color] || colorVariants.gray;
}

// ============================================
// NOTE UTILITIES
// ============================================

/**
 * Get note category config
 *
 * @param category - Note category
 * @returns Category configuration
 */
export function getNoteCategoryConfig(category: string) {
  return NOTE_CATEGORIES[category as keyof typeof NOTE_CATEGORIES] || NOTE_CATEGORIES.GENERAL;
}

/**
 * Get note category badge classes
 *
 * @param category - Note category
 * @returns Tailwind CSS classes
 */
export function getNoteCategoryBadgeClasses(category: string): string {
  const config = getNoteCategoryConfig(category);

  // Static color variants mapping for Tailwind JIT compiler
  const colorVariants: Record<string, string> = {
    blue: 'bg-blue-50 text-blue-700 border-blue-200',
    purple: 'bg-purple-50 text-purple-700 border-purple-200',
    emerald: 'bg-emerald-50 text-emerald-700 border-emerald-200',
    amber: 'bg-amber-50 text-amber-700 border-amber-200',
    gray: 'bg-gray-50 text-gray-700 border-gray-200',
    green: 'bg-green-50 text-green-700 border-green-200',
    orange: 'bg-orange-50 text-orange-700 border-orange-200',
    red: 'bg-red-50 text-red-700 border-red-200',
    yellow: 'bg-yellow-50 text-yellow-700 border-yellow-200',
    pink: 'bg-pink-50 text-pink-700 border-pink-200',
    rose: 'bg-rose-50 text-rose-700 border-rose-200',
    slate: 'bg-slate-50 text-slate-700 border-slate-200',
  };

  return colorVariants[config.color] || colorVariants.gray;
}

// ============================================
// ANALYTICS UTILITIES
// ============================================

/**
 * Calculate percentage
 *
 * @param part - Part value
 * @param total - Total value
 * @param decimals - Number of decimal places
 * @returns Percentage string
 */
export function calculatePercentage(
  part: number,
  total: number,
  decimals: number = 1
): string {
  if (total === 0) return '0';
  return ((part / total) * 100).toFixed(decimals);
}

/**
 * Format number with thousands separator
 *
 * @param num - Number to format
 * @returns Formatted number string
 */
export function formatNumber(num: number): string {
  return num.toLocaleString('en-US');
}

/**
 * Calculate success rate from counts
 *
 * @param successful - Number of successful attempts
 * @param total - Total attempts
 * @returns Success rate percentage
 */
export function calculateSuccessRate(successful: number, total: number): number {
  if (total === 0) return 0;
  return Math.round((successful / total) * 100 * 100) / 100;
}

// ============================================
// IP & LOCATION UTILITIES
// ============================================

/**
 * Format IP and location for display
 *
 * @param ip - IP address
 * @param country - Country name
 * @param city - City name
 * @returns Formatted string
 */
export function formatIPLocation(
  ip: string | null,
  country: string | null,
  city: string | null
): string {
  if (!ip) return '-';

  const parts = [];
  if (city) parts.push(city);
  if (country) parts.push(country);

  const location = parts.join(', ');
  return location ? `${ip} (${location})` : ip;
}

/**
 * Check if IP is private/local
 *
 * @param ip - IP address
 * @returns True if private IP
 */
export function isPrivateIP(ip: string): boolean {
  if (ip === '127.0.0.1' || ip === '::1') return true;
  if (ip.startsWith('192.168.')) return true;
  if (ip.startsWith('10.')) return true;
  if (/^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(ip)) return true;
  if (ip.startsWith('169.254.')) return true;
  return false;
}

// ============================================
// VALIDATION UTILITIES
// ============================================

/**
 * Check if staff has permission
 *
 * @param staffRole - Staff member's role
 * @param requiredRoles - Required roles
 * @returns True if has permission
 */
export function hasPermission(staffRole: string, requiredRoles: string[]): boolean {
  return requiredRoles.includes(staffRole);
}

/**
 * Sanitize HTML for safe display
 *
 * @param html - HTML string
 * @returns Sanitized HTML
 */
export function sanitizeHTML(html: string): string {
  // Basic HTML escaping (use DOMPurify in production)
  return html
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}
