import 'dart:async';
import 'dart:convert';
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:location/location.dart';
import 'package:syncfusion_flutter_maps/maps.dart';

class MapTestController extends GetxController {
  late MapShapeSource mapSource;
  late MapShapeSource kozigSource;
  late MapZoomPanBehavior zoomPanBehavior;
  late MapTileLayerController mapTileLayerController;

  late List<MapLatLng> line1, line2, line3;
  late List<List<MapLatLng>> lines1, lines2, lines3;
  late List<MapModel> mapModel = [];

  late StreamSubscription<LocationData> locationSubscription;
  bool locationSubscriptionIsInitialized = false;
  Location location = Location();
  RxDouble currentLongitude = 18.122495576634044.obs;
  RxDouble currentLatitude = 46.328746702592106.obs;
  RxBool isInitialized = false.obs;

  @override
  void onInit() async {
    mapTileLayerController = MapTileLayerController();
    bool res = await loadMapData();

    location.changeSettings(
        accuracy: LocationAccuracy.high, interval: 500, distanceFilter: 1);

    line1 = const <MapLatLng>[
      MapLatLng(46.409474083913345, 18.196055479431202),
      MapLatLng(46.40229074049568, 18.184834829804377),
      MapLatLng(46.400881093344097, 18.183525800449701),
      MapLatLng(46.392903944366708, 18.177253122976378),
      MapLatLng(46.384773311328807, 18.170585406188426),
      MapLatLng(46.382049391318191, 18.168012348371033),
      MapLatLng(46.381677738114753, 18.167665852333496),
      MapLatLng(46.381161940383038, 18.167149737333396),
      MapLatLng(46.377534073316291, 18.164141681038203),
      MapLatLng(46.374368645392636, 18.161698675385864),
      MapLatLng(46.370683914933664, 18.158587091204133),
      MapLatLng(46.3640763356468, 18.153155234991335),
      MapLatLng(46.363576961214015, 18.152317669751312),
      MapLatLng(46.35389201272092, 18.13590711186691),
      MapLatLng(46.352978857192532, 18.133309083714881),
      MapLatLng(46.35137058576526, 18.13098235253349),
      MapLatLng(46.348440208996635, 18.126684238252697),
      MapLatLng(46.347130535026032, 18.123117395006844),
      MapLatLng(46.34706818966626, 18.122931136322965),
      MapLatLng(46.346565571573841, 18.122161191477915),
      MapLatLng(46.346370011622788, 18.121391157301662),
      MapLatLng(46.342636923837361, 18.112691291995962),
      MapLatLng(46.342389315173889, 18.111910189208963),
      MapLatLng(46.333172947557394, 18.099415040392927),
      MapLatLng(46.32863226668006, 18.087695666266029),
      MapLatLng(46.325737435025978, 18.08355812652276),
      // MapLatLng(46.322053106393668, 18.078583447909164),
      // MapLatLng(46.318345777758296, 18.075366997618815),
      // MapLatLng(46.317198167430817, 18.074782985031753),
      // MapLatLng(46.316022015155262, 18.07310019901135),
      // MapLatLng(46.314147548726261, 18.072144612154844),
      // MapLatLng(46.312510626772578, 18.071178953163265),
      // MapLatLng(46.310758970899364, 18.068863947464287),
      // MapLatLng(46.308993975939856, 18.065995601793436),
      // MapLatLng(46.302099673468611, 18.060496509299735),
      // MapLatLng(46.299097775521432, 18.05627769200369),
      // MapLatLng(46.295182331629846, 18.051900556314489),
      // MapLatLng(46.292525209632785, 18.048285539930436),
      // MapLatLng(46.290524900577878, 18.045515378447099)
    ];

    line3 = const <MapLatLng>[
      MapLatLng(46.325737435025978, 18.08355812652276),
      MapLatLng(46.322053106393668, 18.078583447909164),
      MapLatLng(46.318345777758296, 18.075366997618815),
      MapLatLng(46.317198167430817, 18.074782985031753),
      MapLatLng(46.316022015155262, 18.07310019901135),
      MapLatLng(46.314147548726261, 18.072144612154844),
      MapLatLng(46.312510626772578, 18.071178953163265),
      MapLatLng(46.310758970899364, 18.068863947464287),
      MapLatLng(46.308993975939856, 18.065995601793436),
      MapLatLng(46.302099673468611, 18.060496509299735),
      MapLatLng(46.299097775521432, 18.05627769200369),
      MapLatLng(46.295182331629846, 18.051900556314489),
      MapLatLng(46.292525209632785, 18.048285539930436),
      MapLatLng(46.290524900577878, 18.045515378447099)
    ];

    line2 = const <MapLatLng>[
      // MapLatLng(46.260064352706863, 18.116797380886084),
      MapLatLng(46.251888084511876, 18.116765702743511),
      MapLatLng(46.276731538707907, 18.118312495916047),
      MapLatLng(46.290630785869595, 18.121715933401102),
      MapLatLng(46.291602112755918, 18.121615413423505),
      MapLatLng(46.293861019929999, 18.121966080774971),
      MapLatLng(46.306808758830037, 18.120536071329884),
      MapLatLng(46.307565036417657, 18.120339010103002),
      MapLatLng(46.313074623341073, 18.12005586208279),
      MapLatLng(46.315292570695746, 18.120136355999676),
      MapLatLng(46.317610563278862, 18.120225447918834),
      MapLatLng(46.31852533235655, 18.120312832087762),
      MapLatLng(46.324753378018201, 18.120473866804605),
      MapLatLng(46.334486981796822, 18.117343038689867),
      MapLatLng(46.335047155775996, 18.117367081901961),
      MapLatLng(46.337466485256385, 18.116990955631348),
      MapLatLng(46.340277266846968, 18.116562251592601),
      MapLatLng(46.343322881556979, 18.116268008370902),
      MapLatLng(46.347183527547493, 18.113215711471319),
      MapLatLng(46.347908214739213, 18.112661806065514),
      MapLatLng(46.348086908069178, 18.112669488541766),
      MapLatLng(46.348833657599236, 18.113161876278717),
      MapLatLng(46.35355966637772, 18.112136546361285),
      MapLatLng(46.357138992408714, 18.111476412678716)
    ];

    lines2 = [line2];
    lines3 = [line3];
    lines1 = [line1];

    await _getInitialLocation();

    mapSource = MapShapeSource.asset(
      'assets/Files/erintett_telkek_0613.geojson',
      shapeDataField: "id1",
      dataCount: mapModel.length,
      primaryValueMapper: (index) => mapModel[index].id!,
      dataLabelMapper: (index) => mapModel[index].hrsz!,
      shapeColorValueMapper: (index) => mapModel[index].color!,
    );
    kozigSource = const MapShapeSource.asset(
      'assets/Files/kozig_hatar.geojson',
      shapeDataField: "Telepules",
    );

    zoomPanBehavior = MapZoomPanBehavior(
        minZoomLevel: 1,
        maxZoomLevel: 25,
        zoomLevel: 15,
        // focalLatLng: const MapLatLng(46.328746702592106, 18.122495576634044));
        focalLatLng: MapLatLng(currentLatitude.value, currentLongitude.value));

    _listenLocation();

    super.onInit();
    isInitialized.value = true;
  }

  @override
  void onClose() {
    if (locationSubscriptionIsInitialized) {
      locationSubscription.cancel();
    }
    super.onClose();
  }

  Future<void> _getInitialLocation() async {
    bool servicedEnabled;
    PermissionStatus permissionGranted;
    LocationData locationData;
    Location location = Location();

    servicedEnabled = await location.serviceEnabled();
    if (!servicedEnabled) {
      servicedEnabled = await location.requestService();
      if (!servicedEnabled) {
        return;
      }
    }

    permissionGranted = await location.hasPermission();
    if (permissionGranted == PermissionStatus.denied) {
      permissionGranted = await location.requestPermission();
      if (permissionGranted != PermissionStatus.granted) {
        return;
      }
    }

    locationData = await location.getLocation();
    currentLatitude.value = locationData.latitude ?? 0.0;
    currentLongitude.value = locationData.longitude ?? 0.0;
  }

  Future<void> _listenLocation() async {
    locationSubscription =
        location.onLocationChanged.handleError((dynamic err) {
      locationSubscription.cancel();
    }).listen((LocationData currentLocation) {
      currentLatitude.value = currentLocation.latitude!;
      currentLongitude.value = currentLocation.longitude!;
      locationSubscriptionIsInitialized = true;
      log('x: ${currentLatitude.value}  -  y: ${currentLongitude.value}');
      // zoomPanBehavior.focalLatLng =
      //     MapLatLng(currentLatitude.value, currentLongitude.value);
      mapTileLayerController.updateMarkers([0]);
    });
  }

  Future<String> getJsonFromAssets() async {
    return await rootBundle.loadString('assets/Files/telkek_0510.geojson');
  }

  Future<bool> loadMapData() async {
    final String jsonString = await getJsonFromAssets();
    final Map<String, dynamic> jsonResponse = jsonDecode(jsonString);
    List<dynamic> feature = jsonResponse['features'];
    for (int i = 0; i < feature.length; i++) {
      mapModel.add(
          MapModel.fromJson(feature[i]['properties'] as Map<String, dynamic>));
    }

    // _shapeSource = MapShapeSource.asset('assets/usa.json',
    //     shapeDataField: 'name',
    //     dataCount: _mapData.length,
    //     primaryValueMapper: (int index) => _mapData[index].name!,
    //     dataLabelMapper: (int index) => _mapData[index].name!,
    //     shapeColorValueMapper: (int index) => _mapData[index].color);
    return true;
  }
}

class MapModel {
  // Data type
  Color? color;
  String? hrsz;
  String? telepules;
  String? id;

  //constructor
  MapModel({this.id, this.telepules, this.hrsz, this.color});

  // Method that assigns values to respective datatype variables
  factory MapModel.fromJson(Map<String, dynamic> json) {
    Color modelColor = Colors.amber;
    double opacity = 0.5;

    /// While fetching the color codes as String from JSON. Use these codes to convert it as Color.
    //String hexColor = json['COLOR'] as String;
    // Color(int.parse(hexColor.substring(1, 7), radix: 16) + 0xFF000000);

    // log("${json['id1']} - ${json['Telepules']} - ${json['Hrsz']}");

    String telepules = json['Telepules'];
    if (telepules == 'Jágónak') {
      modelColor = Color.fromRGBO(55, 88, 187, opacity);
    } else if (telepules == 'Baranyajenő') {
      modelColor = Color.fromRGBO(159, 65, 214, opacity);
    } else if (telepules == 'Kercseliget') {
      modelColor = Color.fromRGBO(235, 209, 63, opacity);
    } else if (telepules == 'Dombóvár') {
      modelColor = Color.fromRGBO(99, 219, 169, opacity);
    } else if (telepules == 'Kaposszekcső') {
      modelColor = Color.fromRGBO(202, 122, 86, opacity);
    } else if (telepules == 'Csikóstőttős') {
      modelColor = Color.fromRGBO(145, 43, 43, opacity);
    } else if (telepules == 'Baranyajenő') {
      modelColor = Color.fromRGBO(159, 65, 214, opacity);
    } else if (telepules == 'Vásárosdombó') {
      modelColor = Color.fromRGBO(51, 238, 60, opacity);
    } else if (telepules == 'Meződ') {
      modelColor = Color.fromRGBO(99, 212, 216, opacity);
    } else if (telepules == 'Tarrós') {
      modelColor = Color.fromRGBO(224, 203, 236, opacity);
    } else if (telepules == 'Vázsnok') {
      modelColor = Color.fromRGBO(74, 155, 8, opacity);
    } else if (telepules == 'Sásd') {
      modelColor = Color.fromRGBO(143, 91, 112, opacity);
    }

    return MapModel(
        id: json['id1'] as String,
        telepules: json['Telepules'],
        hrsz: json['Hrsz'],
        color: modelColor);
  }
}
