import 'dart:async';
import 'dart:convert';
import 'dart:ui';

import 'package:android_intent/android_intent.dart';
import 'package:chat/utils/loading_builder.dart';
import 'package:chat/utils/log.dart';
import 'package:chat/utils/screen_shot.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';

import 'location_provider.dart';
import 'location_result.dart';
import 'package:http/http.dart' as http;

class MapPicker extends StatefulWidget {
  final LatLng initialCenter;
  final String apiKey;
  final bool requiredGPS;

  const MapPicker({
    Key key,
    this.initialCenter,
    this.apiKey,
    this.requiredGPS,
  }) : super(key: key);

  @override
  MapPickerState createState() => MapPickerState();
}

class MapPickerState extends State<MapPicker> {
  Completer<GoogleMapController> mapController = Completer();
  GlobalKey rootWidgetKey = GlobalKey();

  LatLng _lastMapPosition;

  Position _currentPosition;

  String _address;

  // void _onToggleMapTypePressed() {
  //   final MapType nextType =
  //       MapType.values[(_currentMapType.index + 1) % MapType.values.length];

  //   setState(() => _currentMapType = nextType);
  // }

  // this also checks for location permission.
  Future<void> _initCurrentLocation() async {
    Position currentPosition;
    try {
      currentPosition = await Geolocator()
          .getCurrentPosition(desiredAccuracy: LocationAccuracy.best);

      d("position = $currentPosition");

      setState(() => _currentPosition = currentPosition);
    } on PlatformException catch (e) {
      currentPosition = null;
      d("_initCurrentLocation#e = $e");
    }

    if (!mounted) return;

    setState(() => _currentPosition = currentPosition);

    if (currentPosition != null)
      moveToCurrentLocation(
          LatLng(currentPosition.latitude, currentPosition.longitude));
  }

  @override
  void initState() {
    super.initState();
    _initCurrentLocation();
  }

  @override
  void dispose() {
    rootWidgetKey = null;
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (widget.requiredGPS) {
      _checkGps();
      _checkGeolocationPermission();
    }
    return Scaffold(
      body: Builder(builder: (context) {
        if (_currentPosition == null && widget.requiredGPS)
          return const Center(child: CircularProgressIndicator());

        return buildMap();
      }),
    );
  }

  Widget buildMap() {
    return Center(
      child: Stack(
        children: <Widget>[
          GoogleMap(
              onMapCreated: (GoogleMapController controller) {
                mapController.complete(controller);

                _lastMapPosition = widget.initialCenter;
                LocationProvider.of(context)
                    .setLastIdleLocation(_lastMapPosition);
              },
              initialCameraPosition: CameraPosition(
                target: widget.initialCenter,
                zoom: 18.0,
              ),
              onCameraMove: (CameraPosition position) {
                _lastMapPosition = position.target;
              },
              onCameraIdle: () async {
                LocationProvider.of(context)
                    .setLastIdleLocation(_lastMapPosition);
              },
              myLocationEnabled: true,
              myLocationButtonEnabled: true),
          // _MapFabs(
          //   onToggleMapTypePressed: _onToggleMapTypePressed,
          // ),
          pin(),
          locationCard(),
        ],
      ),
    );
  }

  Widget locationCard() {
    return Align(
      alignment: Alignment.bottomCenter,
      child: Padding(
        padding: const EdgeInsets.fromLTRB(8, 8, 8, 24),
        child: Card(
          child: Padding(
            padding: const EdgeInsets.all(8),
            child: Consumer<LocationProvider>(
                builder: (context, locationProvider, _) {
              return Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Flexible(
                    flex: 20,
                    child: FutureLoadingBuilder<String>(
                        future: getAddress(locationProvider.lastIdleLocation),
                        mutable: true,
                        loadingIndicator: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            CircularProgressIndicator(),
                          ],
                        ),
                        builder: (context, address) {
                          _address = address;
                          return Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Text(
                                address ?? 'Unnamed place',
                                 textScaleFactor: 1.0,
                                style: TextStyle(
                                  fontSize: 18,
                                ),
                              ),
                            ],
                          );
                        }),
                  ),
                  Spacer(),
                  FloatingActionButton(
                    onPressed: () async {
                      var capture = await ScreenShot.takeScreenshotImage();

                      Navigator.of(context).pop({
                        'location': LocationResult(
                            latLng: locationProvider.lastIdleLocation,
                            address: _address,
                            screen: capture),
                      });
                    },
                    child: Icon(Icons.send, color: Colors.white),
                  ),
                ],
              );
            }),
          ),
        ),
      ),
    );
  }

  Future<String> getAddress(LatLng latLng) async {
    try {

      /*
      var placeMarks = await Geolocator()
          .placemarkFromCoordinates(latLng.latitude, latLng.longitude);

      if (placeMarks == null) {
        return null;
      }
      var place = placeMarks.first;

      print('place  ${place.toJson()}');
      return place.name;
  */
      

      var endPoint =
          'https://maps.googleapis.com/maps/api/geocode/json?latlng=${latLng?.latitude},${latLng?.longitude}&key=${widget.apiKey}';
      var response = jsonDecode((await http.get(endPoint)).body);

      return response['results'][0]['formatted_address'];
      
    } catch (e) {
      print(e);
    }

    return null;
  }

  Center pin() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(Icons.place, size: 56, color: Colors.lightBlue),
          Container(
            decoration: ShapeDecoration(
              shadows: [
                BoxShadow(
                  color: Colors.black38,
                  blurRadius: 4,
                ),
              ],
              shape: CircleBorder(
                side: BorderSide(
                  width: 4,
                  color: Colors.transparent,
                ),
              ),
            ),
          ),
          SizedBox(height: 56),
        ],
      ),
    );
  }

  Future moveToCurrentLocation(LatLng currentLocation) async {
    var controller = await mapController.future;
    controller.animateCamera(CameraUpdate.newCameraPosition(
      CameraPosition(target: currentLocation, zoom: 18.0),
    ));
  }

  var dialogOpen;

  Future _checkGeolocationPermission() async {
    var geolocationStatus =
        await Geolocator().checkGeolocationPermissionStatus();

    if (geolocationStatus == GeolocationStatus.denied && dialogOpen == null) {
      d('showDialog');
      dialogOpen = showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) {
          return AlertDialog(
            title: Text('Access to location denied'),
            content: Text('Allow access to the location services.'),
            actions: <Widget>[
              FlatButton(
                child: Text('Ok'),
                onPressed: () {
                  Navigator.of(context, rootNavigator: true).pop();
                  _initCurrentLocation();
                  dialogOpen = null;
                },
              ),
            ],
          );
        },
      );
    //} else if (geolocationStatus == GeolocationStatus.disabled) {
    } else if (geolocationStatus == GeolocationStatus.granted) {
      d('GeolocationStatus.granted');
      if (dialogOpen != null) {
        Navigator.of(context, rootNavigator: true).pop();
        dialogOpen = null;
      }
    }
  }

  Future _checkGps() async {
    if (!(await Geolocator().isLocationServiceEnabled())) {
      if (Theme.of(context).platform == TargetPlatform.android) {
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text("Can't get current location"),
              content: Text('Please make sure you enable GPS and try again'),
              actions: <Widget>[
                FlatButton(
                  child: Text('Ok'),
                  onPressed: () {
                    final AndroidIntent intent = AndroidIntent(
                        action: 'android.settings.LOCATION_SOURCE_SETTINGS');

                    intent.launch();
                    Navigator.of(context, rootNavigator: true).pop();
                  },
                ),
              ],
            );
          },
        );
      }
    }
  }
}

/*
class _MapFabs extends StatelessWidget {
  const _MapFabs({
    Key key,
    @required this.onToggleMapTypePressed,
  })  : assert(onToggleMapTypePressed != null),
        super(key: key);

  final VoidCallback onToggleMapTypePressed;

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.topRight,
      margin: const EdgeInsets.only(top: 64, right: 8),
      child: Column(
        children: <Widget>[
          FloatingActionButton(
            onPressed: onToggleMapTypePressed,
            materialTapTargetSize: MaterialTapTargetSize.padded,
            mini: true,
            child: const Icon(Icons.layers, size: 28, color: Colors.white),
            heroTag: "layers",
          ),
        ],
      ),
    );
  }
}*/
