import 'package:flutter/services.dart';

/// 전화번호 관련 유틸리티 클래스 (SRP, 재사용성, 테스트 용이성 중심)
class PhoneUtils {
  /// 전화번호 입력 형식 지정용 InputFormatter
  static final TextInputFormatter phoneInputFormatter =
      _PhoneTextInputFormatter();

  /// 전화번호 포맷팅 (뒤 4자리 하이페)
  static String formatPhoneNumber(String phoneNumber) {
    final digitsOnly = phoneNumber.replaceAll(RegExp(r'[^\d]'), '');
    if (digitsOnly.isEmpty) return '';
    if (digitsOnly.length > 8) {
      return formatPhoneNumber(digitsOnly.substring(0, 8));
    }
    if (digitsOnly.length > 4) {
      final frontPart = digitsOnly.substring(0, digitsOnly.length - 4);
      final backPart = digitsOnly.substring(digitsOnly.length - 4);
      return '$frontPart-$backPart';
    }
    return digitsOnly;
  }
  
  /// 접두사에 따른 전화번호 포맷팅
  /// 010, 070, 050 등 0x0 번호: 0000-0000
  /// 02, 031 등 지역번호: 000-0000 또는 0000-0000
  static String formatPhoneNumberByPrefix(String prefix, String phoneNumber) {
    final digitsOnly = phoneNumber.replaceAll(RegExp(r'[^\d]'), '');
    if (digitsOnly.isEmpty) return '';
    
    // 0x0 형태의 번호 (010, 070, 050 등)
    if (prefix.length == 3 && prefix.startsWith('0') && prefix[2] == '0') {
      // 8자리 처리: 0000-0000
      if (digitsOnly.length == 8) {
        return '${digitsOnly.substring(0, 4)}-${digitsOnly.substring(4)}';
      } else if (digitsOnly.length > 8) {
        final trimmed = digitsOnly.substring(0, 8);
        return '${trimmed.substring(0, 4)}-${trimmed.substring(4)}';
      } else if (digitsOnly.length > 4) {
        return '${digitsOnly.substring(0, 4)}-${digitsOnly.substring(4)}';
      }
    }
    // 지역번호 (02, 031, 032 등)
    else {
      // 7자리: 000-0000
      if (digitsOnly.length == 7) {
        return '${digitsOnly.substring(0, 3)}-${digitsOnly.substring(3)}';
      }
      // 8자리: 0000-0000
      else if (digitsOnly.length == 8) {
        return '${digitsOnly.substring(0, 4)}-${digitsOnly.substring(4)}';
      }
      // 그 외: 마지막 4자리 앞에 하이픈
      else if (digitsOnly.length > 4) {
        final frontPart = digitsOnly.substring(0, digitsOnly.length - 4);
        final backPart = digitsOnly.substring(digitsOnly.length - 4);
        return '$frontPart-$backPart';
      }
    }
    
    return digitsOnly;
  }

  /// 포맷된 전화번호에서 숫자만 추출
  static String extractDigitsOnly(String formattedPhoneNumber) {
    return formattedPhoneNumber.replaceAll(RegExp(r'[^\d]'), '');
  }

  /// 전체 전화번호에서 접두사 추출 (없으면 기본값)
  static String extractPhonePrefix(
    String fullNumber,
    List<String> phonePrefixes,
  ) {
    if (fullNumber.isEmpty) return '010';
    String digitsOnly = fullNumber.replaceAll(RegExp(r'[^\d]'), '');
    for (String prefix in phonePrefixes) {
      if (digitsOnly.startsWith(prefix)) {
        return prefix;
      }
    }
    return '010';
  }

  /// 접두사 제외한 번호 추출
  static String extractPhoneNumberWithoutPrefix(
    String fullNumber,
    List<String> phonePrefixes,
  ) {
    if (fullNumber.isEmpty) return '';
    String digitsOnly = fullNumber.replaceAll(RegExp(r'[^\d]'), '');
    for (String prefix in phonePrefixes) {
      if (digitsOnly.startsWith(prefix)) {
        return digitsOnly.substring(prefix.length);
      }
    }
    return digitsOnly;
  }

  /// 접두사와 번호를 합쳐 전체 전화번호 생성 (완전한 형태로 포맷팅)
  /// 서버 전송용: "010-1234-5678" 또는 "02-123-4567" 형태
  static String getFullPhoneNumber(String prefix, String number) {
    final remainingNumber = number.replaceAll(RegExp(r'[^\d]'), '');
    if (remainingNumber.isEmpty) return '';
    
    // 접두사에 따른 완전한 전화번호 포맷팅
    if (prefix.length == 3 && prefix.startsWith('0') && prefix[2] == '0') {
      // 0x0 형태 (010, 070, 050 등): 010-1234-5678
      if (remainingNumber.length >= 8) {
        final trimmed = remainingNumber.length > 8 ? remainingNumber.substring(0, 8) : remainingNumber;
        return '$prefix-${trimmed.substring(0, 4)}-${trimmed.substring(4)}';
      } else if (remainingNumber.length > 4) {
        return '$prefix-${remainingNumber.substring(0, 4)}-${remainingNumber.substring(4)}';
      }
      return '$prefix-$remainingNumber';
    } else {
      // 지역번호 (02, 031 등): 02-123-4567 또는 031-1234-5678
      if (remainingNumber.length >= 7) {
        if (remainingNumber.length == 7) {
          return '$prefix-${remainingNumber.substring(0, 3)}-${remainingNumber.substring(3)}';
        } else { // 8자리
          return '$prefix-${remainingNumber.substring(0, 4)}-${remainingNumber.substring(4)}';
        }
      } else if (remainingNumber.length > 3) {
        return '$prefix-${remainingNumber.substring(0, 3)}-${remainingNumber.substring(3)}';
      }
      return '$prefix-$remainingNumber';
    }
  }
  /// 자주 사용되는 전화번호 접두사 목록 반환
  static List<String> getCommonPhonePrefixes() {
    return [
      '010',
      '011',
      '016',
      '017',
      '018',
      '019',
      '070',
      '080',
      '02',
      '031',
      '032',
      '033',
      '041',
      '042',
      '043',
      '044',
      '051',
      '052',
      '053',
      '054',
      '055',
      '061',
      '062',
      '063',
      '064',
    ];
  }
}

/// 전화번호 입력 형식 지정용 TextInputFormatter (내부 전용)
class _PhoneTextInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue,
    TextEditingValue newValue,
  ) {
    final digitsOnly = newValue.text.replaceAll(RegExp(r'[^\d]+'), '');
    final trimmed =
        digitsOnly.length > 11 ? digitsOnly.substring(0, 11) : digitsOnly;
    String formatted = '';
    if (trimmed.length > 7) {
      formatted =
          '${trimmed.substring(0, 3)}-${trimmed.substring(3, 7)}-${trimmed.substring(7)}';
    } else if (trimmed.length > 3) {
      formatted = '${trimmed.substring(0, 3)}-${trimmed.substring(3)}';
    } else {
      formatted = trimmed;
    }
    int selectionIndex =
        newValue.selection.end + (formatted.length - newValue.text.length);
    if (selectionIndex < 0) selectionIndex = 0;
    if (selectionIndex > formatted.length) selectionIndex = formatted.length;
    return TextEditingValue(
      text: formatted,
      selection: TextSelection.collapsed(offset: selectionIndex),
    );
  }
}
