// ignore_for_file: unnecessary_library_name

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

import 'package:flutter_test/flutter_test.dart';
import 'package:lunchpick/data/datasources/remote/naver_map_parser.dart';
import 'package:lunchpick/data/api/naver/naver_local_search_api.dart';
import '../../../../mocks/mock_naver_api_client.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('NaverMapParser 위치 기반 필터링 테스트', () {
    late NaverMapParser parser;
    late MockNaverApiClient mockApiClient;

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

    test('사용자 위치가 제공되면 가장 가까운 식당을 선택해야 함', () async {
      // Given
      const url = 'https://naver.me/xtest1234';
      const finalUrl = 'https://map.naver.com/p/restaurant/1234567890';
      const placeId = '1234567890';
      const placeName = '스타벅스';
      const userLat = 37.5665;
      const userLng = 126.9780;

      // 단축 URL 리디렉션 설정
      mockApiClient.setUrlRedirect(url, finalUrl);

      // pcmap에서 장소명 추출 설정
      mockApiClient.setPlaceName(placeId, placeName);

      // 검색 결과 - 여러 개의 스타벅스
      final searchResults = [
        NaverLocalSearchResult(
          title: '스타벅스 강남역점',
          link: 'https://map.naver.com/p/restaurant/9999999999',
          category: '카페>커피전문점',
          description: '',
          telephone: '02-1234-5678',
          address: '서울특별시 강남구 강남대로 123',
          roadAddress: '서울특별시 강남구 강남대로 123',
          mapx: 1269780000, // 126.978 * 10000000
          mapy: 375650000, // 37.565 * 10000000 (더 가까움)
        ),
        NaverLocalSearchResult(
          title: '스타벅스 시청점',
          link: 'https://map.naver.com/p/restaurant/1234567890', // Place ID 일치
          category: '카페>커피전문점',
          description: '',
          telephone: '02-2345-6789',
          address: '서울특별시 중구 세종대로 110',
          roadAddress: '서울특별시 중구 세종대로 110',
          mapx: 1269784147, // 126.9784147 * 10000000
          mapy: 375666805, // 37.5666805 * 10000000 (정확히 일치)
        ),
        NaverLocalSearchResult(
          title: '스타벅스 홍대입구점',
          link: 'https://map.naver.com/p/restaurant/8888888888',
          category: '카페>커피전문점',
          description: '',
          telephone: '02-3456-7890',
          address: '서울특별시 마포구 양화로 123',
          roadAddress: '서울특별시 마포구 양화로 123',
          mapx: 1269250000, // 126.925 * 10000000
          mapy: 375560000, // 37.556 * 10000000 (더 멈)
        ),
      ];

      mockApiClient.setSearchResults(placeName, searchResults);

      // When
      final result = await parser.parseRestaurantFromUrl(
        url,
        userLatitude: userLat,
        userLongitude: userLng,
      );

      // Then
      expect(result.name, '스타벅스 시청점');
      expect(result.naverPlaceId, placeId);
    });

    test('위치 정보가 없으면 첫 번째 결과를 사용해야 함', () async {
      // Given
      const url = 'https://naver.me/xtest1234';
      const finalUrl = 'https://map.naver.com/p/restaurant/1234567890';
      const placeId = '1234567890';
      const placeName = '스타벅스';

      // 단축 URL 리디렉션 설정
      mockApiClient.setUrlRedirect(url, finalUrl);

      // pcmap에서 장소명 추출 설정
      mockApiClient.setPlaceName(placeId, placeName);

      // 검색 결과
      final searchResults = [
        NaverLocalSearchResult(
          title: '스타벅스 강남역점',
          link: 'https://map.naver.com/p/restaurant/9999999999',
          category: '카페>커피전문점',
          description: '',
          telephone: '02-1234-5678',
          address: '서울특별시 강남구 강남대로 123',
          roadAddress: '서울특별시 강남구 강남대로 123',
          mapx: 1269780000,
          mapy: 375650000,
        ),
      ];

      mockApiClient.setSearchResults(placeName, searchResults);

      // When
      final result = await parser.parseRestaurantFromUrl(url);

      // Then
      expect(result.name, '스타벅스 강남역점');
    });

    test('HTML에서 첫 번째 한글 텍스트를 상호명으로 추출해야 함', () async {
      // Given
      const placeId = '1492377618';
      const mockHtml = '''
        <html>
        <body>
          <div><span class="GHAhO">카페 칼리스타 구로본점</span><span class="lnJFt">카페,디저트</span></div>
          <div>영업시간: 09:00 - 22:00</div>
        </body>
        </html>
      ''';

      // pcmap HTML 응답 설정
      mockApiClient.setHtmlResponse(
        'https://pcmap.place.naver.com/place/$placeId/home',
        mockHtml,
      );

      // 장소명 설정
      mockApiClient.setPlaceName(placeId, '카페 칼리스타 구로본점');

      // When
      final placeName = await mockApiClient.fetchPlaceNameFromPcmap(placeId);

      // Then
      expect(placeName, '카페 칼리스타 구로본점');
    });

    test('거리 계산이 정확해야 함', () async {
      // Given
      const url = 'https://naver.me/xtest1234';
      const finalUrl = 'https://map.naver.com/p/restaurant/1234567890';
      const placeId = '1234567890';
      const placeName = '테스트 식당';

      // 서울시청 좌표
      const userLat = 37.5666805;
      const userLng = 126.9784147;

      // 단축 URL 리디렉션 설정
      mockApiClient.setUrlRedirect(url, finalUrl);

      // pcmap에서 장소명 추출 설정
      mockApiClient.setPlaceName(placeId, placeName);

      // 검색 결과 - 거리가 다른 두 곳
      final searchResults = [
        NaverLocalSearchResult(
          title: '테스트 식당 A점 (500m)',
          link: 'https://map.naver.com/p/restaurant/1111111111',
          category: '음식점',
          description: '',
          telephone: '',
          address: '서울특별시',
          roadAddress: '서울특별시',
          mapx: 1269789000, // 약 500m 떨어진 곳
          mapy: 375671000,
        ),
        NaverLocalSearchResult(
          title: '테스트 식당 B점 (1km)',
          link: 'https://map.naver.com/p/restaurant/2222222222',
          category: '음식점',
          description: '',
          telephone: '',
          address: '서울특별시',
          roadAddress: '서울특별시',
          mapx: 1269873000, // 약 1km 떨어진 곳
          mapy: 375676000,
        ),
      ];

      mockApiClient.setSearchResults(placeName, searchResults);

      // When
      final result = await parser.parseRestaurantFromUrl(
        url,
        userLatitude: userLat,
        userLongitude: userLng,
      );

      // Then - 더 가까운 A점이 선택되어야 함
      expect(result.name.contains('A점'), true);
    });
  });
}
