import 'package:uuid/uuid.dart';

import '../../../domain/entities/restaurant.dart';
import '../naver/naver_local_search_api.dart';
import '../../../core/utils/category_mapper.dart';

/// 네이버 데이터 변환기
///
/// 네이버 API 응답을 도메인 엔티티로 변환합니다.
class NaverDataConverter {
  static const _uuid = Uuid();

  /// NaverLocalSearchResult를 Restaurant 엔티티로 변환
  static Restaurant fromLocalSearchResult(
    NaverLocalSearchResult result, {
    String? id,
  }) {
    // 좌표 변환 (네이버 지도 좌표계 -> WGS84)
    final convertedCoords = _convertNaverMapCoordinates(
      result.mapx,
      result.mapy,
    );

    // 카테고리 파싱 및 정규화
    final categoryParts = result.category
        .split('>')
        .map((s) => s.trim())
        .toList();
    final mainCategory = categoryParts.isNotEmpty ? categoryParts.first : '음식점';
    final subCategory = categoryParts.length > 1
        ? categoryParts.last
        : mainCategory;

    // CategoryMapper를 사용한 정규화
    final normalizedCategory = CategoryMapper.normalizeNaverCategory(
      mainCategory,
      subCategory,
    );

    return Restaurant(
      id: id ?? _uuid.v4(),
      name: result.title,
      category: normalizedCategory,
      subCategory: subCategory,
      description: result.description.isNotEmpty ? result.description : null,
      phoneNumber: result.telephone.isNotEmpty ? result.telephone : null,
      roadAddress: result.roadAddress.isNotEmpty
          ? result.roadAddress
          : result.address,
      jibunAddress: result.address,
      latitude: convertedCoords['latitude'] ?? 37.5665,
      longitude: convertedCoords['longitude'] ?? 126.9780,
      naverUrl: result.link.isNotEmpty ? result.link : null,
      createdAt: DateTime.now(),
      updatedAt: DateTime.now(),
      source: DataSource.NAVER,
    );
  }

  /// GraphQL 응답을 Restaurant 엔티티로 변환
  static Restaurant fromGraphQLResponse(
    Map<String, dynamic> placeData, {
    String? id,
    String? naverUrl,
  }) {
    // 영업시간 파싱
    String? businessHours;
    if (placeData['businessHours'] != null) {
      final hours = placeData['businessHours'] as List;
      businessHours = hours
          .where((h) => h['businessHours'] != null)
          .map((h) => h['businessHours'])
          .join('\n');
    }

    // 좌표 추출
    double? latitude;
    double? longitude;
    if (placeData['location'] != null) {
      latitude = placeData['location']['latitude']?.toDouble();
      longitude = placeData['location']['longitude']?.toDouble();
    }

    // 카테고리 파싱 및 정규화
    final rawCategory = placeData['category'] ?? '음식점';
    final categoryParts = rawCategory.split('>').map((s) => s.trim()).toList();
    final mainCategory = categoryParts.isNotEmpty ? categoryParts.first : '음식점';
    final subCategory = categoryParts.length > 1
        ? categoryParts.last
        : mainCategory;

    // CategoryMapper를 사용한 정규화
    final normalizedCategory = CategoryMapper.normalizeNaverCategory(
      mainCategory,
      subCategory,
    );

    return Restaurant(
      id: id ?? _uuid.v4(),
      name: placeData['name'] ?? '이름 없음',
      category: normalizedCategory,
      subCategory: subCategory,
      description: placeData['description'],
      phoneNumber: placeData['phone'],
      roadAddress: placeData['address']?['roadAddress'] ?? '',
      jibunAddress: placeData['address']?['jibunAddress'] ?? '',
      latitude: latitude ?? 37.5665,
      longitude: longitude ?? 126.9780,
      businessHours: businessHours,
      naverUrl: naverUrl,
      createdAt: DateTime.now(),
      updatedAt: DateTime.now(),
      source: DataSource.NAVER,
    );
  }

  /// 네이버 지도 좌표를 WGS84로 변환
  static Map<String, double?> _convertNaverMapCoordinates(
    double? mapx,
    double? mapy,
  ) {
    if (mapx == null || mapy == null) {
      return {'latitude': null, 'longitude': null};
    }

    // 네이버 지도 좌표계는 KATEC을 사용
    // 간단한 변환 공식 (정확도는 떨어지지만 실용적)
    // 실제로는 더 정교한 변환이 필요할 수 있음
    final longitude = mapx / 10000000.0;
    final latitude = mapy / 10000000.0;

    return {'latitude': latitude, 'longitude': longitude};
  }
}
