import 'package:injectable/injectable.dart';
import 'package:superport/core/constants/app_constants.dart';
import 'package:superport/data/models/zipcode_dto.dart';
import 'package:superport/data/repositories/zipcode_repository.dart';

abstract class ZipcodeUseCase {
  /// 우편번호 검색 (페이지네이션 지원)
  Future<ZipcodeListResponse> searchZipcodes({
    int page = 1,
    int limit = AppConstants.defaultPageSize,
    String? search,
    String? sido,
    String? gu,
  });

  /// 검색어 유효성 검사 및 정규화
  String normalizeSearchQuery(String query);
  
  /// Hierarchy API - 시도 목록 조회
  Future<HierarchyResponse> getHierarchySidos();
  
  /// Hierarchy API - 구/군 목록 조회
  Future<HierarchyResponse> getHierarchyGusBySido(String sido);
}

@Injectable(as: ZipcodeUseCase)
class ZipcodeUseCaseImpl implements ZipcodeUseCase {
  final ZipcodeRepository _repository;

  ZipcodeUseCaseImpl(this._repository);

  @override
  Future<ZipcodeListResponse> searchZipcodes({
    int page = 1,
    int limit = AppConstants.defaultPageSize,
    String? search,
    String? sido,
    String? gu,
  }) async {
    // 비즈니스 로직: 페이지네이션 유효성 검사
    if (page < 1) page = 1;
    if (limit < 1 || limit > 100) limit = AppConstants.defaultPageSize;

    // 검색어 정규화
    final normalizedSearch = search != null && search.isNotEmpty 
        ? normalizeSearchQuery(search) 
        : null;

    return await _repository.search(
      page: page,
      limit: limit,
      search: normalizedSearch,
      sido: sido?.trim(),
      gu: gu?.trim(),
    );
  }


  @override
  String normalizeSearchQuery(String query) {
    if (query.trim().isEmpty) return '';

    String normalized = query.trim();
    
    // 공백 정규화 (여러 공백을 하나로)
    normalized = normalized.replaceAll(RegExp(r'\s+'), ' ');
    
    // 특수문자 제거 (단, 한글, 영문, 숫자, 공백, 하이픈만 유지)
    normalized = normalized.replaceAll(RegExp(r'[^\w\s가-힣ㄱ-ㅎㅏ-ㅣ-]'), '');
    
    return normalized;
  }

  @override
  Future<HierarchyResponse> getHierarchySidos() async {
    return await _repository.getHierarchySidos();
  }

  @override
  Future<HierarchyResponse> getHierarchyGusBySido(String sido) async {
    if (sido.trim().isEmpty) {
      throw ArgumentError('시도명을 입력해주세요.');
    }
    
    return await _repository.getHierarchyGusBySido(sido.trim());
  }

}