import 'package:intl/intl.dart'; import '../constants/app_constants.dart'; /// 데이터 포맷터 유틸리티 클래스 class Formatters { /// 날짜 포맷 static String formatDate(DateTime date) { return DateFormat(AppConstants.dateFormat).format(date); } /// 날짜+시간 포맷 static String formatDateTime(DateTime dateTime) { return DateFormat(AppConstants.dateTimeFormat).format(dateTime); } /// 상대적 시간 포맷 (예: 3분 전, 2시간 전) static String formatRelativeTime(DateTime dateTime) { final now = DateTime.now(); final difference = now.difference(dateTime); if (difference.inDays > 365) { return '${(difference.inDays / 365).floor()}년 전'; } else if (difference.inDays > 30) { return '${(difference.inDays / 30).floor()}개월 전'; } else if (difference.inDays > 0) { return '${difference.inDays}일 전'; } else if (difference.inHours > 0) { return '${difference.inHours}시간 전'; } else if (difference.inMinutes > 0) { return '${difference.inMinutes}분 전'; } else { return '방금 전'; } } /// 숫자 포맷 (천 단위 구분) static String formatNumber(int number) { return NumberFormat('#,###').format(number); } /// 통화 포맷 static String formatCurrency(int amount) { return NumberFormat.currency( locale: 'ko_KR', symbol: '₩', decimalDigits: 0, ).format(amount); } /// 전화번호 포맷 static String formatPhone(String phone) { final cleaned = phone.replaceAll(RegExp(r'[^0-9]'), ''); if (cleaned.length == 11) { return '${cleaned.substring(0, 3)}-${cleaned.substring(3, 7)}-${cleaned.substring(7)}'; } else if (cleaned.length == 10) { if (cleaned.startsWith('02')) { return '${cleaned.substring(0, 2)}-${cleaned.substring(2, 6)}-${cleaned.substring(6)}'; } else { return '${cleaned.substring(0, 3)}-${cleaned.substring(3, 6)}-${cleaned.substring(6)}'; } } return phone; } /// 사업자번호 포맷 static String formatBusinessNumber(String businessNumber) { final cleaned = businessNumber.replaceAll(RegExp(r'[^0-9]'), ''); if (cleaned.length == 10) { return '${cleaned.substring(0, 3)}-${cleaned.substring(3, 5)}-${cleaned.substring(5)}'; } return businessNumber; } /// 파일 크기 포맷 static String formatFileSize(int bytes) { if (bytes < 1024) { return '$bytes B'; } else if (bytes < 1024 * 1024) { return '${(bytes / 1024).toStringAsFixed(1)} KB'; } else if (bytes < 1024 * 1024 * 1024) { return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB'; } else { return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB'; } } /// 백분율 포맷 static String formatPercentage(double value, {int decimals = 0}) { return '${(value * 100).toStringAsFixed(decimals)}%'; } /// 기간 포맷 (일수) static String formatDuration(int days) { if (days >= 365) { final years = days ~/ 365; final remainingDays = days % 365; if (remainingDays > 0) { return '$years년 $remainingDays일'; } return '$years년'; } else if (days >= 30) { final months = days ~/ 30; final remainingDays = days % 30; if (remainingDays > 0) { return '$months개월 $remainingDays일'; } return '$months개월'; } else { return '$days일'; } } /// 상태 텍스트 변환 static String formatStatus(String status) { return AppConstants.equipmentStatus[status] ?? status; } /// 역할 텍스트 변환 static String formatRole(String role) { switch (role) { case 'S': case 'admin': return '관리자'; case 'M': case 'manager': return '매니저'; case 'U': case 'staff': return '직원'; case 'V': case 'viewer': return '열람자'; default: return role; } } /// null 값 처리 static String formatNullable(String? value, {String defaultValue = '-'}) { return value?.isEmpty ?? true ? defaultValue : value!; } }