import 'dart:collection';
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:anyway/structs/landmark.dart';
import 'package:anyway/structs/trip.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:widget_to_marker/widget_to_marker.dart';


class MapWidget extends StatefulWidget {

  final Trip? trip;

  MapWidget({
    this.trip
  });

  @override
  State<MapWidget> createState() => _MapWidgetState();
}

class _MapWidgetState extends State<MapWidget> {
  late GoogleMapController mapController;

  CameraPosition _cameraPosition = CameraPosition(
    target: LatLng(48.8566, 2.3522),
    zoom: 11.0,
  );
  Set<Marker> mapMarkers = <Marker>{};
  

  void _onMapCreated(GoogleMapController controller) async {
    mapController = controller;
    List<double>? newLocation = widget.trip?.landmarks.firstOrNull?.location;
    if (newLocation != null) {
      CameraUpdate update = CameraUpdate.newLatLng(LatLng(newLocation[0], newLocation[1]));
      controller.moveCamera(update);
    }
    setMapMarkers();
  }

  void _onCameraIdle() {
    // print(mapController.getLatLng(ScreenCoordinate(x: 0, y: 0)));
  }


  void setMapMarkers() async {
    List<Landmark> landmarks = widget.trip?.landmarks.toList() ?? [];
    Set<Marker> newMarkers = <Marker>{};
    for (int i = 0; i < landmarks.length; i++) {
      Landmark landmark = landmarks[i];
      List<double> location = landmark.location;
      Marker marker = Marker(
        markerId: MarkerId(landmark.uuid),
        position: LatLng(location[0], location[1]),
        icon: await CustomMarker(landmark: landmark, position: i).toBitmapDescriptor(
          logicalSize: const Size(150, 150),
          imageSize: const Size(150, 150)
        ),
      );
      newMarkers.add(marker);
    }
    setState(() {
      mapMarkers = newMarkers;
    });
  }

  @override
  Widget build(BuildContext context) {
    widget.trip?.addListener(setMapMarkers);
    return GoogleMap(
      onMapCreated: _onMapCreated,
      initialCameraPosition: _cameraPosition,
      onCameraIdle: _onCameraIdle,
      // onLongPress: ,
      markers: mapMarkers,
      cloudMapId: '41c21ac9b81dbfd8',
    );
  }
}


class CustomMarker extends StatelessWidget {
  final Landmark landmark;
  final int position;

  CustomMarker({
    super.key,
    required this.landmark,
    required this.position
    });

  @override
  Widget build(BuildContext context) {
    // This returns an outlined circle, with an icon corresponding to the landmark type
    // As a small dot, the number of the landmark is displayed in the top right
    Icon icon;
    if (landmark.type == sightseeing) {
      icon = Icon(Icons.church, color: Colors.black, size: 50);
    } else if (landmark.type == nature) {
      icon = Icon(Icons.park, color: Colors.black, size: 50);
    } else if (landmark.type == shopping) {
      icon = Icon(Icons.shopping_cart, color: Colors.black, size: 50);
    } else if (landmark.type == start || landmark.type == finish) {
      icon = Icon(Icons.flag, color: Colors.black, size: 50);
    } else {
      icon = Icon(Icons.location_on, color: Colors.black, size: 50);
    }

    Widget? positionIndicator;
    if (landmark.type != start && landmark.type != finish) {
      positionIndicator = Positioned(
        top: 0,
        right: 0,
        child: Container(
          padding: EdgeInsets.all(5),
          decoration: BoxDecoration(
            color: Theme.of(context).primaryColor,
            shape: BoxShape.circle,
          ),
          child: Text('$position', style: TextStyle(color: Colors.white, fontSize: 20)),
        ),
      );
    }

    return RepaintBoundary(
      child: Stack(
        children: [
          Container(
            // these are not the final sizes, since the final size is set in the toBitmapDescriptor method
            // they are useful nevertheless to ensure the scale of the components are correct
            width: 75,
            height: 75,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.topLeft,
                end: Alignment.bottomRight,
                colors: [Colors.red, Colors.yellow]
              ),
              shape: BoxShape.circle,
              border: Border.all(color: Colors.black, width: 5),
            ),
            child: icon,
          ),
          positionIndicator ?? Container(),
        ],
      ),
    );
  }
}