import 'dart:async';
import 'package:flutter/services.dart';
import '../../flutter_map.dart';
import '../entity/poi_item.dart';
import '../entity/poi_query.dart';
import '../entity/poi_search_bound.dart';
import 'map_base_platform.dart';
import 'map_platform_impl.dart';

class FlutterMap {
  FlutterMap._();

  static MapBasePlatform? _mapPlatform;
  static Completer<void>? _initCompleter;

  static Future<void> init() {
    if (_mapPlatform != null) return Future.value();

    if (_initCompleter != null) return _initCompleter!.future;

    _initCompleter = Completer<void>();

    const MethodChannel channel = MethodChannel(MapConstants.mapMethodChannel);
    final MapBasePlatform mapPlatform = MapPlatformImpl(channel);

    mapPlatform.init().then((ok) {
      if (!ok) throw Exception("地图初始化失败，未找到适配的地图，请检查是否添加地图库");
      _mapPlatform = mapPlatform;
      _initCompleter?.complete();
    }).catchError((e, stack) {
      _initCompleter?.completeError(e, stack);
    });

    return _initCompleter!.future;
  }

  static Future<String?> getPlatformName() {
    assert(_mapPlatform != null, "请先调用 FlutterMap.init()");
    return _mapPlatform!.getPlatformName();
  }

  static void receiveLocationStream({required MapLocationListener listener}) {
    assert(_mapPlatform != null, "请先调用 FlutterMap.init()");
    _mapPlatform!.receiveLocationStream(listener: listener);
  }

  static Future<void> startLocation() {
    assert(_mapPlatform != null, "请先调用 FlutterMap.init()");
    return _mapPlatform!.startLocation();
  }

  static Future<List<LatLng>?> queryProcessedTrace(
      {required int lineID, required List<TraceLocation> locations}) {
    assert(_mapPlatform != null, "请先调用 FlutterMap.init()");
    return _mapPlatform!
        .queryProcessedTrace(lineID: lineID, locations: locations);
  }

  static Future<List<PoiItem>?> paginatePoiSearch(
      {required int pageNum,
      required int pageSize,
      required PoiQuery query,
      PoiSearchBound? bound}) {
    assert(_mapPlatform != null, "请先调用 FlutterMap.init()");
    return _mapPlatform!.paginatePoiSearch(
        pageNum: pageNum, pageSize: pageSize, query: query, bound: bound);
  }
}
