import 'package:dio/dio.dart';
import 'package:lunchpick/core/utils/app_logger.dart';

import '../../../core/network/network_client.dart';
import '../../../core/errors/network_exceptions.dart';

/// 네이버 GraphQL API 클라이언트
///
/// 네이버 지도의 GraphQL API를 호출하여 상세 정보를 가져옵니다.
class NaverGraphQLApi {
  final NetworkClient _networkClient;

  static const String _graphqlEndpoint =
      'https://pcmap-api.place.naver.com/graphql';

  NaverGraphQLApi({NetworkClient? networkClient})
    : _networkClient = networkClient ?? NetworkClient();

  /// GraphQL 쿼리 실행
  Future<Map<String, dynamic>> fetchGraphQL({
    required String operationName,
    required String query,
    Map<String, dynamic>? variables,
  }) async {
    try {
      final response = await _networkClient.post<Map<String, dynamic>>(
        _graphqlEndpoint,
        data: {
          'operationName': operationName,
          'query': query,
          'variables': variables ?? {},
        },
        options: Options(
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'Referer': 'https://map.naver.com/',
            'Origin': 'https://map.naver.com',
          },
        ),
      );

      if (response.data == null) {
        throw ParseException(message: 'GraphQL 응답이 비어있습니다');
      }

      return response.data!;
    } on DioException catch (e) {
      AppLogger.error(
        'fetchGraphQL error: $e',
        error: e,
        stackTrace: e.stackTrace,
      );
      throw ServerException(
        message: 'GraphQL 요청 중 오류가 발생했습니다',
        statusCode: e.response?.statusCode ?? 500,
        originalError: e,
      );
    }
  }

  /// 장소 상세 정보 가져오기 (한국어 텍스트)
  Future<Map<String, dynamic>> fetchKoreanTextsFromPcmap(String placeId) async {
    const query = '''
    query getKoreanTexts(\$id: String!) {
      place(input: { id: \$id }) {
        id
        name
        category
        businessHours {
          description
          isDayOff
          openTime
          closeTime
          dayOfWeek
          businessHours
        }
        phone
        address {
          roadAddress
          jibunAddress
        }
        description
        menuInfo {
          menus {
            name
            price
            description
            images {
              url
            }
          }
        }
        keywords
        priceCategory
        imageCount
        visitorReviewCount
        visitorReviewScore
      }
    }
    ''';

    try {
      final response = await fetchGraphQL(
        operationName: 'getKoreanTexts',
        query: query,
        variables: {'id': placeId},
      );

      if (response['errors'] != null) {
        AppLogger.error('GraphQL errors: ${response['errors']}');
        throw ParseException(message: 'GraphQL 오류: ${response['errors']}');
      }

      return response['data']?['place'] ?? {};
    } catch (e, stackTrace) {
      AppLogger.error(
        'fetchKoreanTextsFromPcmap error: $e',
        error: e,
        stackTrace: stackTrace,
      );
      rethrow;
    }
  }

  /// 장소 기본 정보 가져오기
  Future<Map<String, dynamic>> fetchPlaceBasicInfo(String placeId) async {
    const query = '''
    query getPlaceBasicInfo(\$id: String!) {
      place(input: { id: \$id }) {
        id
        name
        category
        phone
        address {
          roadAddress
          jibunAddress
        }
        location {
          latitude
          longitude
        }
        homepageUrl
        bookingUrl
      }
    }
    ''';

    try {
      final response = await fetchGraphQL(
        operationName: 'getPlaceBasicInfo',
        query: query,
        variables: {'id': placeId},
      );

      if (response['errors'] != null) {
        throw ParseException(message: 'GraphQL 오류: ${response['errors']}');
      }

      return response['data']?['place'] ?? {};
    } catch (e, stackTrace) {
      AppLogger.error(
        'fetchPlaceBasicInfo error: $e',
        error: e,
        stackTrace: stackTrace,
      );
      rethrow;
    }
  }

  void dispose() {
    // 필요시 리소스 정리
  }
}
