search method

  1. @override
Future<List<PowerMapSearchResult>> search(
  1. String query, {
  2. LatLng? proximity,
  3. String lang = 'auto',
})
override

Implementation

@override
Future<List<PowerMapSearchResult>> search(
  String query, {
  LatLng? proximity,
  String lang = 'auto',
}) async {
  final cleanLang = lang.toLowerCase();
  final hasThai = RegExp(r'[\u0E00-\u0E7F]').hasMatch(query);
  final hasEnglish = RegExp(r'[a-zA-Z]').hasMatch(query);

  String primaryPath = _searchThPath;
  String secondaryPath = _searchEnPath;

  if (cleanLang == 'en') {
    primaryPath = _searchEnPath;
    secondaryPath = _searchThPath;
  } else if (cleanLang == 'th') {
    primaryPath = _searchThPath;
    secondaryPath = _searchEnPath;
  } else {
    // auto mode
    if (hasEnglish && !hasThai) {
      primaryPath = _searchEnPath;
      secondaryPath = _searchThPath;
    } else {
      primaryPath = _searchThPath;
      secondaryPath = _searchEnPath;
    }
  }

  try {
    List<dynamic> primaryData = await _fetchPath(primaryPath, query, proximity);

    // Fallback: If proximity search returned < 3 results, query nationwide (without proximity)
    if (proximity != null && primaryData.length < 3) {
      try {
        final nationwideData = await _fetchPath(primaryPath, query, null);
        if (nationwideData.isNotEmpty) {
          final existingGids = primaryData
              .map((e) => (e['_source'] ?? e)['gid'])
              .where((gid) => gid != null)
              .toSet();
          for (final nwItem in nationwideData) {
            final nwGid = (nwItem['_source'] ?? nwItem)['gid'];
            if (nwGid == null || !existingGids.contains(nwGid)) {
              primaryData.add(nwItem);
              if (nwGid != null) existingGids.add(nwGid);
            }
          }
        }
      } catch (_) {}
    }

    // Perform secondary fetch if primary returned empty OR query has mixed script
    if (primaryData.isEmpty || (cleanLang == 'auto' && hasThai && hasEnglish)) {
      try {
        List<dynamic> secondaryData = await _fetchPath(secondaryPath, query, proximity);
        if (secondaryData.isEmpty && proximity != null) {
          try {
            secondaryData = await _fetchPath(secondaryPath, query, null);
          } catch (_) {}
        }
        if (secondaryData.isNotEmpty) {
          if (primaryData.isEmpty) {
            primaryData = secondaryData;
          } else {
            final existingGids = primaryData
                .map((e) => (e['_source'] ?? e)['gid'])
                .where((gid) => gid != null)
                .toSet();
            for (final secItem in secondaryData) {
              final secGid = (secItem['_source'] ?? secItem)['gid'];
              if (secGid == null || !existingGids.contains(secGid)) {
                primaryData.add(secItem);
                if (secGid != null) existingGids.add(secGid);
              }
            }
          }
        }
      } catch (_) {
        // Ignore secondary fetch errors if primary succeeded
      }
    }

    return primaryData
        .map((item) => PowerMapSearchResult.fromJson(item, lang: lang, query: query))
        .toList();
  } catch (e) {
    if (e is PowerMapException) rethrow;
    throw PowerMapException(
      code: PowerMapException.network,
      message: 'Search request failed due to a network error.',
      details: e,
    );
  }
}