import 'package:flutter/cupertino.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:injectable/injectable.dart';
import 'package:location/base/base_controller.dart';
import 'package:location/data/repositories/account_repository.dart';
import 'package:location/handler/error_handler.dart';
import 'package:location/sdk/map/map_helper.dart';
import 'package:location/utils/atmob_log.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:sliding_sheet2/sliding_sheet2.dart';
import '../../../data/bean/user_info.dart';
import '../../../dialog/common_confirm_dialog_impl.dart';
import '../../../dialog/location_permission_dialog.dart';
import '../../../resource/string.gen.dart';
import '../../../utils/de_bounce.dart';
import '../../../utils/permission_util.dart';
import '../../../utils/toast_util.dart';

@injectable
class CommonPointSelectAddressController extends BaseController {
  final TextEditingController searchEditController = TextEditingController();
  final FocusNode searchFocusNode = FocusNode();

  final mapController = MapController.create();

  final SheetController sheetController = SheetController();

  final RxDouble _commonPointRange = RxDouble(200);

  double get commonPointRange => _commonPointRange.value;

  final RxDouble _sheetProgress = 0.0.obs;

  double get sheetProgress => _sheetProgress.value;

  bool _isRangeChanging = false;

  bool _isFirstMoveCamera = true;

  UserInfo get mineUserInfo => accountRepository.mineUserInfo.value;

  RxList<PoiItem> poiList = RxList();

  final refreshController = RefreshController(initialRefresh: false);

  final Debounce _searchDebounce = Debounce(debounceTime: 500);

  final AccountRepository accountRepository;

  CommonPointSelectAddressController(this.accountRepository);

  final MapPadding mapPadding =
      MapPadding(top: 80, left: 80, right: 80, bottom: 80);

  final CircleOptions circleOptions = CircleOptions(
      fillColor: '#4D7B7DFF', strokeWidth: 2.w, strokeColor: '#92AEE6');

  final PoiQuery _poiQuery = PoiQuery();

  final int _pageSize = 20;
  int _pageNum = 1;

  @override
  void onReady() {
    super.onReady();
    _updateCurrentLocation();
    mapController.setOnCameraChangeListener(
      (camera) {
        if (_isRangeChanging) {
          return;
        }
        if (camera.function == CameraChangeType.onCameraChange) {
          //暂时隐藏范围
          if (circleOptions.visible == true) {
            circleOptions.visible = false;
            _updateOrAddCircle();
          }
        } else {
          circleOptions
            ..radius = commonPointRange
            ..longitude = camera.position.longitude
            ..visible = true
            ..latitude = camera.position.latitude;
          _updateOrAddCircle();
          if (_isFirstMoveCamera) {
            _isFirstMoveCamera = false;
            _moveCameraToBounds();
          }
          //重新还原数据
          _resetPoiQuery();
          _poiSearch();
        }
      },
    );
  }

  void _resetPoiQuery() {
    _pageNum = 1;
  }

  void _poiSearch() async {
    _searchDebounce.onClick(() {
      AtmobLog.d('zk', '_poiSearch: $_poiQuery');
      FlutterMap.paginatePoiSearch(
              pageNum: _pageNum,
              pageSize: _pageSize,
              query: _poiQuery,
              bound: PoiSearchBound.circle(
                  center: LatLng(
                      latitude: circleOptions.latitude,
                      longitude: circleOptions.longitude),
                  radius: circleOptions.radius?.toInt()))
          .then((list) {
        if (_pageNum == 1) {
          poiList.clear();
        }
        if (list != null && list.isNotEmpty) {
          poiList.addAll(list);
          refreshController.loadComplete();
        }
        if (list == null || list.length < _pageSize) {
          refreshController.loadNoData();
        }
      }).catchError((error) {
        ErrorHandler.toastError(error);
        refreshController.loadFailed();
      });
    });
  }

  void _updateOrAddCircle() {
    mapController.updateOrAddCircle('DC', circleOptions);
  }

  void backClick() {
    if (sheetController.state?.isExpanded == true) {
      sheetController.snapToExtent(0,
          duration: const Duration(milliseconds: 250));
      return;
    }
    Get.back();
  }

  void setCommonPointRange(double value) {
    _commonPointRange.value = value;
    circleOptions.radius = value;
    if (circleOptions.visible == true) {
      _updateOrAddCircle();
      _moveCameraToBounds();
    }
  }

  _moveCameraToBounds() {
    final latLngBounds = CameraUpdateUtil.getBounds(circleOptions.latitude,
        circleOptions.longitude, circleOptions.radius ?? 0);
    if (latLngBounds != null) {
      mapController.moveCameraToBounds(latLngBounds, mapPadding: mapPadding);
    }
  }

  setSheetProgress(double progress) {
    _sheetProgress.value = progress;
    if (progress == 1) {
      // _requestFocus();
    }
  }

  void onOpenSearchAddressModel() async {
    if (sheetProgress == 0) {
      _setExpand();
    }
  }

  void _setExpand() async {
    await sheetController.snapToExtent(1,
        duration: const Duration(milliseconds: 250));
    _requestFocus();
  }

  void _requestFocus() async {
    if (searchFocusNode.hasFocus) {
      return;
    }
    //获取焦点
    await Future.delayed(Duration(milliseconds: 150));
    searchFocusNode.requestFocus();
  }

  void setCommonPointRangeStart() {
    _isRangeChanging = true;
  }

  void setCommonPointRangeEnd() {
    _isRangeChanging = false;
  }

  void moveToCurrentLocation() async {
    //权限检查
    bool isGranted = await PermissionUtil.checkLocationPermission();
    if (!isGranted) {
      LocationPermissionDialog.show(onNextStep: _requestLocationPermission);
    } else {
      _updateCurrentLocation();
    }
  }

  void _updateCurrentLocation() {
    var lastLocation = MapHelper.getLastLocation();
    if (lastLocation == null) {
      locationListener(MapLocation location) {
        MapHelper.removeLocationListener(locationListener);
        _showCurrentRange(location);
      }

      MapHelper.addLocationListener(locationListener);
    } else {
      _showCurrentRange(lastLocation);
    }
  }

  void _showCurrentRange(MapLocation location) {
    circleOptions.latitude = location.latitude;
    circleOptions.longitude = location.longitude;
    _moveCameraToBounds();
  }

  void _requestLocationPermission() async {
    bool isGranted = await PermissionUtil.requestLocationPermission();
    if (isGranted) {
      _showLocationAlways();
      _updateCurrentLocation();
    } else {
      permissionRefuseDialog(settingClick: () {
        openAppSettings();
      });
      ToastUtil.show(StringName.permissionRequestFail);
    }
  }

  void _showLocationAlways() async {
    bool isGranted = await PermissionUtil.checkShowLocationAlways();
    if (!isGranted) {
      LocationAlwaysPermissionDialog.show(onNextStep: () async {
        isGranted = await PermissionUtil.requestShowLocationAlways();
        if (isGranted) {
          _updateCurrentLocation();
        }
      });
    }
  }

  onPoiItemClick(PoiItem item) {}

  void onLoadMorePoiData() {
    _pageNum++;
    _poiSearch();
  }
}
