// ignore_for_file: unnecessary_library_name

@Skip('Integration-heavy parser tests are temporarily disabled')
library naver_map_parser_test;

import 'package:flutter_test/flutter_test.dart';
import 'package:lunchpick/data/datasources/remote/naver_map_parser.dart';
import 'package:lunchpick/domain/entities/restaurant.dart';
import 'package:lunchpick/data/api/naver/naver_local_search_api.dart';
import 'package:lunchpick/core/errors/network_exceptions.dart';
import '../../../../mocks/mock_naver_api_client.dart';

void main() {
  late NaverMapParser parser;
  late MockNaverApiClient mockApiClient;

  setUp(() {
    mockApiClient = MockNaverApiClient();
    parser = NaverMapParser(apiClient: mockApiClient);
  });

  tearDown(() {
    parser.dispose();
  });

  group('NaverMapParser', () {
    group('URL 유효성 검증', () {
      test('유효한 네이버 지도 URL을 인식해야 함', () async {
        final validUrls = [
          'https://map.naver.com/p/restaurant/1234567890',
          'https://naver.me/abcdefgh',
          'https://map.naver.com/p/entry/place/1234567890',
        ];

        for (final url in validUrls) {
          mockApiClient.setUrlRedirect(
            url,
            'https://map.naver.com/p/restaurant/1234567890',
          );

          // 검색 API 응답 설정
          mockApiClient.setSearchResults(
            'https://map.naver.com/p/entry/place/1234567890',
            [
              NaverLocalSearchResult.fromJson({
                'title': '테스트 식당',
                'link': 'https://map.naver.com/p/restaurant/1234567890',
                'category': '한식',
                'description': '테스트 설명',
                'telephone': '02-1234-5678',
                'address': '서울 강남구 테스트동 123-45',
                'roadAddress': '서울 강남구 테스트로 123',
                'mapx': 1269780000,
                'mapy': 375665000,
              }),
            ],
          );

          final result = await parser.parseRestaurantFromUrl(url);
          expect(result, isA<Restaurant>(), reason: 'URL: $url');
          expect(result.name, '테스트 식당', reason: 'URL: $url');
        }
      });

      test('잘못된 URL은 예외를 던져야 함', () async {
        final invalidUrls = [
          'https://www.google.com',
          'https://map.kakao.com',
          'https://naver.com',
          'not-a-url',
          '',
        ];

        for (final url in invalidUrls) {
          expect(
            () => parser.parseRestaurantFromUrl(url),
            throwsA(isA<NaverMapParseException>()),
            reason: 'URL: $url should throw exception',
          );
        }
      });
    });

    group('API 응답 처리', () {
      test('검색 API로 식당 정보를 이지해야 함', () async {
        const url = 'https://map.naver.com/p/restaurant/1234567890';
        mockApiClient.setUrlRedirect(url, url);

        // 검색 API 응답 설정
        mockApiClient.setSearchResults(
          'https://map.naver.com/p/entry/place/1234567890',
          [
            NaverLocalSearchResult.fromJson({
              'title': '맛있는 한식당',
              'link': 'https://map.naver.com/p/restaurant/1234567890',
              'category': '한식>고기요리',
              'description': '평일 11:00 - 22:00, 주말 10:00 - 23:00',
              'telephone': '02-123-4567',
              'address': '서울 강남구 역삼동 123-45',
              'roadAddress': '서울 강남구 테헤란로 123',
              'mapx': 1270396000,
              'mapy': 375012000,
            }),
          ],
        );

        final result = await parser.parseRestaurantFromUrl(url);

        expect(result, isA<Restaurant>());
        expect(result.name, '맛있는 한식당');
        expect(result.category, '한식');
        expect(result.description, contains('평일 11:00 - 22:00'));
        expect(result.phoneNumber, '02-123-4567');
        expect(result.roadAddress, '서울 강남구 테헤란로 123');
        expect(result.latitude, closeTo(37.5012, 0.0001));
        expect(result.longitude, closeTo(127.0396, 0.0001));
      });

      test('GraphQL API로 식당 정보를 가져와야 함', () async {
        const url = 'https://map.naver.com/p/restaurant/9876543210';
        mockApiClient.setUrlRedirect(url, url);

        // GraphQL 응답 설정
        mockApiClient.setGraphQLResponse({
          'places': [
            {
              'id': '9876543210',
              'name': '메타태그 식당',
              'category': '기타',
              'description': '맛있는 음식점',
              'address': '서울시 강남구',
              'roadAddress': '서울시 강남구 테헤란로',
              'phone': '02-987-6543',
              'location': {'lat': 37.5, 'lng': 127.0},
            },
          ],
        });

        final result = await parser.parseRestaurantFromUrl(url);

        expect(result, isA<Restaurant>());
        expect(result.name, '메타태그 식당');
        expect(result.category, '기타');
      });

      test('필수 정보가 없으면 기본값을 사용해야 함', () async {
        const url = 'https://map.naver.com/p/restaurant/1234567890';
        mockApiClient.setUrlRedirect(url, url);

        // 빈 GraphQL 응답
        mockApiClient.setGraphQLResponse({});

        // HTML 파싱도 실패하도록 설정
        mockApiClient.setHtmlResponse(url, '<html></html>');

        final result = await parser.parseRestaurantFromUrl(url);

        // 기본값이 사용되어야 함
        expect(result, isA<Restaurant>());
        expect(result.name, contains('1234567890'));
        expect(result.category, '음식점');
      });
    });

    group('단축 URL 처리', () {
      test('단축 URL을 실제 URL로 변환해야 함', () async {
        const shortUrl = 'https://naver.me/abc123';
        const actualUrl = 'https://map.naver.com/p/restaurant/1234567890';

        mockApiClient.setUrlRedirect(shortUrl, actualUrl);

        // 단축 URL용 한글 텍스트 추출 응답
        mockApiClient.setKoreanTextsData('1234567890', {
          'success': true,
          'koreanTexts': ['리다이렉트 식당'],
          'jsonLdName': '리다이렉트 식당',
          'apolloStateName': null,
        });

        // 검색 API 응답 설정
        mockApiClient.setSearchResults('리다이렉트 식당', [
          NaverLocalSearchResult.fromJson({
            'title': '리다이렉트 식당',
            'link': actualUrl,
            'category': '카페',
            'description': '',
            'telephone': '',
            'address': '서울 마포구',
            'roadAddress': '서울 마포구 테스트로 100',
            'mapx': 1268900000,
            'mapy': 375200000,
          }),
        ]);

        final result = await parser.parseRestaurantFromUrl(shortUrl);

        expect(result, isA<Restaurant>());
        expect(result.name, '리다이렉트 식당');
        expect(result.category, '카페');
      });
    });

    group('에러 처리', () {
      test('네트워크 오류 시 예외를 던져야 함', () async {
        const url = 'https://map.naver.com/p/restaurant/network-error';

        mockApiClient.shouldThrowError = true;
        mockApiClient.errorMessage = 'Network error';

        expect(() => parser.parseRestaurantFromUrl(url), throwsException);
      });

      test('429 에러 시 적절한 예외를 던져야 함', () async {
        const url = 'https://map.naver.com/p/restaurant/1234567890';
        mockApiClient.setUrlRedirect(url, url);

        // 429 에러 설정
        mockApiClient.setThrow429Error();

        expect(
          () => parser.parseRestaurantFromUrl(url),
          throwsA(isA<RateLimitException>()),
        );
      });
    });
  });
}
