import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:geojson_vi/geojson_vi.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:gifunavi/pages/destination/destination_controller.dart';
import 'package:gifunavi/pages/index/index_controller.dart';
import 'package:gifunavi/utils/const.dart';

class LocationService {



  static Future<GeoJSONFeatureCollection?> loadLocationsFor(
      String perfecture, String cat) async {
    final IndexController indexController = Get.find<IndexController>();
    String url = "";
    String serverUrl = ConstValues.currentServer();

    if (cat.isNotEmpty) {
      if (indexController.currentUser.isNotEmpty) {
        bool rog = indexController.currentUser[0]['user']['is_rogaining'];
        String r = rog == true ? 'True' : 'False';
        var grp = indexController.currentUser[0]['user']['event_code'];
        url = '$serverUrl/api/inperf/?rog=$r&perf=$perfecture&cat=$cat';
      } else {
        url = '$serverUrl/api/inperf/?perf=$perfecture&cat=$cat';
      }
    } else {
      if (indexController.currentUser.isNotEmpty) {
        bool rog = indexController.currentUser[0]['user']['is_rogaining'];
        String r = rog == true ? 'True' : 'False';
        var grp = indexController.currentUser[0]['user']['event_code'];
        url = '$serverUrl/api/inperf/?rog=$r&perf=$perfecture';
      } else {
        url = '$serverUrl/api/inperf/?perf=$perfecture';
      }
    }
    //print('++++++++$url');
    final response = await http.get(
      Uri.parse(url),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
    );

    if (response.statusCode == 200) {
      GeoJSONFeatureCollection cc =
          GeoJSONFeatureCollection.fromJSON(utf8.decode(response.bodyBytes));
      //print(cc);
      return cc; //featuresFromGeoJson(utf8.decode(response.bodyBytes));
    }
    return null;
  }

  static Future<List<dynamic>?> getLocationsExt(String token) async {
    List<dynamic> ext = [];
    String serverUrl = ConstValues.currentServer();
    String url = '$serverUrl/api/locsext/';
    //print('++++++++$url');
    final response = await http.post(Uri.parse(url),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
          'Authorization': 'Token $token'
        },
        body: jsonEncode(<String, String>{
          'token': token,
        }));

    if (response.statusCode == 200) {
      ext = json.decode(utf8.decode(response.bodyBytes));
    }
    return ext;
  }

  static Future<GeoJSONFeatureCollection?> loadLocationsBound(
      double lat1,
      double lon1,
      double lat2,
      double lon2,
      double lat3,
      double lon3,
      double lat4,
      double lon4,
      String cat,
      String eventCode) async {
    //print("-------- in location for bound -------------");
    final IndexController indexController = Get.find<IndexController>();
    final updateTime = indexController.lastUserUpdateTime.value;

    // ユーザー情報の更新を最大5秒間待つ

    try {
      /*
      // ユーザー情報の更新を最大5秒間待つ
      final newUpdateTime = await indexController.lastUserUpdateTime.stream
          .firstWhere(
            (time) => time.isAfter(updateTime),
        orElse: () => updateTime,
      ).timeout(Duration(seconds: 5));

      if (newUpdateTime == updateTime) {
        print('ユーザー情報の更新がタイムアウトしました');
        // タイムアウト時の処理（例：エラー表示やリトライ）
        return null;
      }
       */

      /*
      await indexController.lastUserUpdateTime.stream.firstWhere(
            (time) => time.isAfter(updateTime),
        orElse: () => updateTime,
      ).timeout(Duration(seconds: 2), onTimeout: () => updateTime);
       */

      String url = "";
      String serverUrl = ConstValues.currentServer();
      if (cat.isNotEmpty) {
        if (indexController.currentUser.isNotEmpty) {
          bool rog = indexController.currentUser[0]['user']['is_rogaining'];
          String r = rog == true ? 'True' : 'False';
          var grp = eventCode; //indexController.currentUser[0]['user']['event_code'];
          print("Group=$grp");
          url =
          '$serverUrl/api/inbound2?rog=$r&grp=$grp&ln1=$lon1&la1=$lat1&ln2=$lon2&la2=$lat2&ln3=$lon3&la3=$lat3&ln4=$lon4&la4=$lat4&cat=$cat';
        } else {
          url =
          '$serverUrl/api/inbound2?ln1=$lon1&la1=$lat1&ln2=$lon2&la2=$lat2&ln3=$lon3&la3=$lat3&ln4=$lon4&la4=$lat4&cat=$cat';
        }
      } else {
        if (indexController.currentUser.isNotEmpty) {
          bool rog = indexController.currentUser[0]['user']['is_rogaining'];
          String r = rog == true ? 'True' : 'False';
          var grp = indexController.currentUser[0]['user']['event_code'];
          print("-------- requested user group $grp -------------");
          url =
          '$serverUrl/api/inbound2?rog=$r&grp=$grp&ln1=$lon1&la1=$lat1&ln2=$lon2&la2=$lat2&ln3=$lon3&la3=$lat3&ln4=$lon4&la4=$lat4';
        } else {
          url =
          '$serverUrl/api/inbound2?ln1=$lon1&la1=$lat1&ln2=$lon2&la2=$lat2&ln3=$lon3&la3=$lat3&ln4=$lon4&la4=$lat4';
        }
        print('++++++++$url');
        final response = await http.get(
          Uri.parse(url),
          headers: <String, String>{
            'Content-Type': 'application/json; charset=UTF-8',
          },
        );

        if (response.statusCode == 500) {
          return null; //featuresFromGeoJson(utf8.decode(response.bodyBytes));
        }

        if (response.statusCode == 200) {
          DestinationController destinationController =
          Get.find<DestinationController>();

          GeoJSONFeatureCollection cc =
          GeoJSONFeatureCollection.fromJSON(utf8.decode(response.bodyBytes));
          if (cc.features.isEmpty) {
            return null;
          } else {
            //print("---- feature got from server is ${cc.collection[0].properties} ------");
            return cc;
          }
        }
      }
    } catch(e) {
      print("Error: $e");
    }

    return null;
  }

  static Future<GeoJSONFeatureCollection?> loadCustomLocations(
      String name, String cat) async {
    final IndexController indexController = Get.find<IndexController>();
    String url = "";
    if (cat == "-all-") {
      cat = "";
    }
    String serverUrl = ConstValues.currentServer();
    //print("loadCustomLocations url is ----- $cat");
    if (cat.isNotEmpty) {
      if (indexController.currentUser.isNotEmpty) {
        bool rog = indexController.currentUser[0]['user']['is_rogaining'];
        String r = rog == true ? 'True' : 'False';
        var grp = indexController.currentUser[0]['user']['event_code'];
        url = '$serverUrl/api/custom_area/?rog=$r&&cat=$cat';
      } else {
        url = '$serverUrl/api/custom_area/?&cat=$cat';
      }
    } else {
      if (indexController.currentUser.isNotEmpty) {
        bool rog = indexController.currentUser[0]['user']['is_rogaining'];
        String r = rog == true ? 'True' : 'False';
        var grp = indexController.currentUser[0]['user']['event_code'];
        url = '$serverUrl/api/customarea?rog=$r&name=$name';
      } else {
        url = '$serverUrl/api/customarea?name=$name';
      }
    }
    //print('++++++++$url');
    final response = await http.get(
      Uri.parse(url),
      headers: <String, String>{
        'Content-Type': 'application/json; charset=UTF-8',
      },
    );

    if (response.statusCode == 500) {
      return null; //featuresFromGeoJson(utf8.decode(response.bodyBytes));
    }

    if (response.statusCode == 200) {
      GeoJSONFeatureCollection cc =
          GeoJSONFeatureCollection.fromJSON(utf8.decode(response.bodyBytes));
      if (cc.features.isEmpty) {
        return null;
      } else {
        return cc;
      }
    }
    return null;
  }

  static const platform = MethodChannel('location');

  static Future<bool> isLocationServiceRunning() async {
    try {
      final bool isRunning = await platform.invokeMethod('isLocationServiceRunning');
      return isRunning;
    } catch (e) {
      print("Failed to check if location service is running: $e");
      return false;
    }
  }
}
