import 'dart:async';
import 'dart:io';
//import 'dart:convert';
//import 'dart:developer';
import 'package:gifunavi/model/gps_data.dart';
//import 'package:gifunavi/pages/home/home_page.dart';
import 'package:gifunavi/utils/database_gps.dart';
import 'package:flutter/material.dart';
//import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
//import 'package:vm_service/vm_service.dart';
//import 'package:dart_vm_info/dart_vm_info.dart';
import 'package:timezone/data/latest.dart' as tz;

import 'package:gifunavi/pages/settings/settings_controller.dart';

import 'package:gifunavi/pages/destination/destination_controller.dart';
import 'package:gifunavi/pages/index/index_binding.dart';
import 'package:gifunavi/pages/index/index_controller.dart';
import 'package:gifunavi/routes/app_pages.dart';
import 'package:gifunavi/utils/location_controller.dart';
import 'package:gifunavi/utils/string_values.dart';
import 'package:gifunavi/widgets/debug_widget.dart';
import 'package:shared_preferences/shared_preferences.dart';
// import 'package:is_lock_screen/is_lock_screen.dart';

//import 'package:gifunavi/services/device_info_service.dart';
import 'package:gifunavi/services/error_service.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
//import 'dart:async';
//import 'package:get/get.dart';
import 'package:flutter/services.dart';

import 'package:permission_handler/permission_handler.dart';

import 'pages/permission/permission.dart';
import 'package:gifunavi/services/api_service.dart';

import 'package:gifunavi/provider/cached_tile_provider.dart';
//import 'package:gifunavi/pages/entry/entry_controller.dart';
//import 'package:gifunavi/pages/team/team_controller.dart';

import 'package:timezone/timezone.dart' as tz;

import 'package:gifunavi/services/motion_service.dart';

Map<String, dynamic> deviceInfo = {};

/*
void saveGameState() async {
  DestinationController destinationController =
      Get.find<DestinationController>();
  SharedPreferences pref = await SharedPreferences.getInstance();
  pref.setBool("is_in_rog", destinationController.isInRog.value);
  pref.setBool(
      "rogaining_counted", destinationController.rogainingCounted.value);
  pref.setBool("ready_for_goal", DestinationController.ready_for_goal);
}
 */

// 現在のユーザーのIDも一緒に保存するようにします。
Future<void> saveGameState() async {
  DestinationController destinationController =
  Get.find<DestinationController>();
  IndexController indexController = Get.find<IndexController>();
  SharedPreferences pref = await SharedPreferences.getInstance();
  debugPrint("ゲームステータス保存　 = ${indexController.currentUser}");
  if(indexController.currentUser.isNotEmpty) {
    pref.setInt("user_id", indexController.currentUser[0]["user"]["id"]);

    if(indexController.currentUser[0]["user"]["event_date"]!=null) {
      final date = indexController.currentUser[0]["user"]["event_date"];
      pref.setString('eventDate', date.toIso8601String());

      debugPrint("Saved date is ${date} => ${date.toIso8601String()}");

      pref.setString('eventCode', indexController.currentUser[0]["user"]["event_code"]);
      pref.setString('teamName', indexController.currentUser[0]["user"]["team_name"]);
      pref.setString('group', indexController.currentUser[0]["user"]["group"]);
      //final zekken = indexController.currentUser[0]["user"]["zekken_number"];
      pref.setInt('zekkenNumber', indexController.currentUser[0]["user"]["zekken_number"]);
    }
  }else{
    debugPrint("User is empty....");
  }
  pref.setBool("is_in_rog", destinationController.isInRog.value);
  pref.setBool(
      "rogaining_counted", destinationController.rogainingCounted.value);
  pref.setBool("ready_for_goal", DestinationController.ready_for_goal);
}



//       _indexController.currentUser[0]["user"]["event_date"] = entryDate;  // 追加2024-8-9
//       _indexController.currentUser[0]["user"]["event_code"] = entry.event.eventName;
//       _indexController.currentUser[0]["user"]["team_name"] = entry.team.teamName;
//       _indexController.currentUser[0]["user"]["group"] = entry.team.category.categoryName;
//       _indexController.currentUser[0]["user"]["zekken_number"] = entry.zekkenNumber;

Future<void> restoreGame() async {
  SharedPreferences pref = await SharedPreferences.getInstance();

  IndexController indexController = Get.find<IndexController>();
  int? savedUserId = pref.getInt("user_id");
  //int? currUserId = indexController.currentUser[0]['user']['id'];
  debugPrint("ゲームステータス再現　 savedUserId=${savedUserId}");
  if (indexController.currentUser.isNotEmpty &&
      indexController.currentUser[0]["user"]["id"] == savedUserId) {

    final dateString = pref.getString('eventDate');
    if (dateString != null) {
      final parsedDate = DateTime.parse(dateString);
      final jstDate = tz.TZDateTime.from(parsedDate, tz.getLocation('Asia/Tokyo'));
      debugPrint("restore date is ${dateString} => ${jstDate}");
      indexController.currentUser[0]["user"]["event_date"] = jstDate;
      //indexController.currentUser[0]["user"]["event_date"] = DateTime.parse(dateString);
    }
    //debugPrint("restore date is ${dateString?} => ${DateTime.parse(dateString)}");

    indexController.currentUser[0]["user"]["event_code"] = pref.getString('eventCode');
    indexController.currentUser[0]["user"]["team_name"]  = pref.getString('teamName');
    indexController.currentUser[0]["user"]["group"] = pref.getString('group');
    indexController.currentUser[0]["user"]["zekken_number"] = pref.getInt('zekkenNumber');

    debugPrint("user = ${indexController.currentUser[0]["user"]}");

    DestinationController destinationController = Get.find<DestinationController>();
    destinationController.skipGps = false;
    destinationController.isInRog.value = pref.getBool("is_in_rog") ?? false;
    destinationController.rogainingCounted.value = pref.getBool("rogaining_counted") ?? false;
    DestinationController.ready_for_goal = pref.getBool("ready_for_goal") ?? false;
    //await Get.putAsync(() => ApiService().init());

    if (indexController.currentUser[0]["user"]["event_code"] != null) {
      indexController.setSelectedEventName(indexController.currentUser[0]["user"]["event_code"]);
    } else {
      indexController.setSelectedEventName('未参加');
    }

  }else{
    indexController.setSelectedEventName('未参加');
  }
}

/*
void restoreGame_new() async {
  SharedPreferences pref = await SharedPreferences.getInstance();
  IndexController indexController = Get.find<IndexController>();

  DestinationController destinationController = Get.find<DestinationController>();
  destinationController.skipGps = false;
  destinationController.isInRog.value = pref.getBool("is_in_rog") ?? false;
  destinationController.rogainingCounted.value = pref.getBool("rogaining_counted") ?? false;
  DestinationController.ready_for_goal = pref.getBool("ready_for_goal") ?? false;

  int? savedUserId = pref.getInt("user_id");
  if (indexController.currentUser.isNotEmpty && indexController.currentUser[0]["user"]["id"] == savedUserId) {
    final dateString = pref.getString('eventDate');
    if (dateString != null) {
      indexController.currentUser[0]["user"]["event_date"] = DateTime.parse(dateString);
    }
    indexController.currentUser[0]["user"]["event_code"] = pref.getString('eventCode');
    indexController.currentUser[0]["user"]["team_name"] = pref.getString('teamName');
    indexController.currentUser[0]["user"]["group"] = pref.getString('group');
    indexController.currentUser[0]["user"]["zekken_number"] = pref.getInt('zekkenNumber');

    if (indexController.currentUser[0]["user"]["event_code"] != null) {
      indexController.setSelectedEventName(indexController.currentUser[0]["user"]["event_code"]);
    } else {
      indexController.setSelectedEventName('未参加');
      _showEventSelectionWarning();
      Get.toNamed(AppPages.EVENT_ENTRY);
    }
  } else {
    indexController.setSelectedEventName('未参加');
    _showEventSelectionWarning();
    Get.toNamed(AppPages.EVENT_ENTRY);
  }

  await Get.putAsync(() => ApiService().init());
}

 */

void _showEventSelectionWarning() {
  Get.dialog(
    AlertDialog(
      title: Text('警告'),
      content: Text('イベントを選択してください。'),
      actions: [
        TextButton(
          child: Text('OK'),
          onPressed: () => Get.back(),
        ),
      ],
    ),
  );
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  if (Platform.isIOS) {
    // アプリの起動時にモーション更新を開始
    await MotionService.startMotionUpdates();
  }

  final IndexController _indexController;

  FlutterError.onError = (FlutterErrorDetails details) {
    FlutterError.presentError(details);
    Get.log('Flutter error: ${details.exception}');
    Get.log('Stack trace: ${details.stack}');
    ErrorService.reportError(details.exception, details.stack ?? StackTrace.current, deviceInfo, LogManager().operationLogs);
  };

  try {


    await initServices();

    runApp(const ProviderScope(child: MyApp()));
  }catch(e, stackTrace){
    print('Error during initialization: $e');
    print('Stack trace: $stackTrace');

    // エラーが発生した場合、エラー画面を表示
    runApp(ErrorApp(error: e.toString()));
  }
}

Future<void> initServices() async {
  print('Starting services ...');
  try {
    //await Get.putAsync(() => ApiService().init());
    await _initApiService();
    debugPrint("1: start ApiService");

    // コントローラーを初期化
    Get.put(IndexController(apiService: Get.find<ApiService>()), permanent: true);
    Get.put(SettingsController(), permanent: true);
    Get.put(DestinationController(), permanent: true);
    Get.put(LocationController(), permanent: true);

    debugPrint("2: Controllers initialized");
    /*
    // すべてのコントローラーとサービスを非同期で初期化
    Get.lazyPut(() => IndexController(apiService: Get.find<ApiService>()));
    debugPrint("2: start IndexController");

    // その他のコントローラーを遅延初期化
    Get.lazyPut(() => SettingsController());
    debugPrint("2: start SettingsController");
    Get.lazyPut(() => DestinationController());
    debugPrint("3: start DestinationController");
    Get.lazyPut(() => LocationController());
    debugPrint("4: start LocationController");
    */

    // 非同期処理を並列実行
    await Future.wait([
      _initTimeZone(),
      _initCacheProvider(),
    ]);

    print('=== 5. Initialized TimeZone...');
    print('=== 6. CacheProvider started...');

    Get.put(PermissionController());
    await _checkPermissions();
    debugPrint("7: start PermissionController");

  }catch(e){
    print('Error initializing : $e');
  }
  print('All services started...');

}

Future<void> _initLocationController() async {
  if (!Get.isRegistered<LocationController>()) {
    Get.put(LocationController());
  }
  print('=== 1. LocationController started...');
}

Future<void> _initTimeZone() async {
  tz.initializeTimeZones();
}

Future<void> _initCacheProvider() async {
  await CacheProvider.initialize();
}

Future<void> _checkPermissions() async {
  await PermissionController.checkAndRequestPermissions();
}

Future<void> _initApiService() async {
  await Get.putAsync(() => ApiService().init());
  //Get.lazyPut(() => ApiService());
}

class ErrorApp extends StatelessWidget {
  final String error;

  const ErrorApp({super.key, required this.error});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text('アプリの起動中にエラーが発生しました: $error'),
        ),
      ),
    );
  }
  }

Future<void> requestLocationPermission() async {
  try {
    final status = await Permission.locationAlways.request();
    if (status == PermissionStatus.granted) {
      print('Location permission granted');
    } else {
      print('Location permission denied');
      //await showLocationPermissionDeniedDialog(); // 追加
    }
  } catch (e) {
    print('Error requesting location permission: $e');
  }
}



// メモリ使用量の解説：https://qiita.com/hukusuke1007/items/e4e987836412e9bc73b9

/*
// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810
// startMemoryMonitoring関数が5分ごとに呼び出され、メモリ使用量をチェックします。
// メモリ使用量が閾値（ここでは500MB）を超えた場合、エラーメッセージとスタックトレースをレポートします。
//
void startMemoryMonitoring()  {
  const threshold = 500 * 1024 * 1024; // 500MB

  // メモリ使用量情報を取得
  final memoryUsage = MemoryUsage.fromJson(DartVMInfo.getAllocationProfile());

  if (memoryUsage.heapUsage > threshold) {
    final now = DateTime.now().toIso8601String();
    final message = 'High memory usage detected at $now: ${memoryUsage.heapUsage} bytes';
    print(message);
    reportError(message, StackTrace.current);
    showMemoryWarningDialog();
  }

  Timer(const Duration(minutes: 5), startMemoryMonitoring);
}

class MemoryUsage {
  final int heapUsage;

  MemoryUsage({required this.heapUsage});

  factory MemoryUsage.fromJson(Map<String, dynamic> json) {
    return MemoryUsage(
      heapUsage: json['heapUsage'] as int,
    );
  }
}
*/

// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810
// reportError関数でエラーレポートを送信します。具体的な実装は、利用するエラー報告サービスによって異なります。
void reportError(String message, StackTrace stackTrace) async {
  // エラーレポートの送信処理を実装
  // 例: SentryやFirebase Crashlyticsなどのエラー報告サービスを利用
  print("ReportError : $message . stacktrace : $stackTrace");
}

// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810
// showMemoryWarningDialog関数で、メモリ使用量が高い場合にユーザーに警告ダイアログを表示します。
//
void showMemoryWarningDialog() {
  if (Get.context != null) {
    showDialog(
      context: Get.context!,
      builder: (context) => AlertDialog(
        title: const Text('メモリ使用量の警告'),
        content: const Text('アプリのメモリ使用量が高くなっています。アプリを再起動することをお勧めします。'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('OK'),
          ),
        ],
      ),
    );
  }
}

StreamSubscription<Position>? positionStream;
bool background=false;
DateTime lastGPSCollectedTime=DateTime.now();
String team_name="";
String event_code="";

Future<void> startBackgroundTracking() async {
  try {
    if (Platform.isIOS && background == false) {
      final IndexController indexController = Get.find<IndexController>();
      if (indexController.currentUser.isNotEmpty &&
          indexController.currentUser[0]["user"]['team_name'] != null) {
        team_name = indexController.currentUser[0]["user"]['team_name'];
        event_code = indexController.currentUser[0]["user"]["event_code"];
      }
      background = true;
      debugPrint("バックグラウンド処理を開始しました。");
      const LocationSettings locationSettings = LocationSettings(
        accuracy: LocationAccuracy.high,
        distanceFilter: 100,
      );

      try {
        positionStream =
            Geolocator.getPositionStream(locationSettings: locationSettings)
                .listen((Position? position) async {
              if (position != null) {
                final lat = position.latitude;
                final lng = position.longitude;
                //final timestamp = DateTime.now();
                final accuracy = position.accuracy;

                // GPS信号強度がlowの場合はスキップ
                if (accuracy > 100) {
                  debugPrint(
                      "GPS signal strength is low. Skipping data saving.");
                  return;
                }

                Duration difference = lastGPSCollectedTime.difference(
                    DateTime.now())
                    .abs();
                // 最後にGPS信号を取得した時刻から10秒以上経過、かつ10m以上経過（普通に歩くスピード）
                //debugPrint("時間差：${difference}");
                if (difference.inSeconds >= 10) {
                  debugPrint(
                      "バックグラウンドでのGPS取得時の処理(10secおき) count=${difference
                          .inSeconds}, time=${DateTime.now()}");

                  // DBにGPSデータを保存 pages/destination/destination_controller.dart
                  await addGPStoDB(lat, lng);

                  lastGPSCollectedTime = DateTime.now();
                }
              }
            }, onError: (error) {
              if (error is LocationServiceDisabledException) {
                print('Location services are disabled');
              } else if (error is PermissionDeniedException) {
                print('Location permissions are denied');
              } else {
                print('Location Error: $error');
              }
            });
      } catch (e) {
        print('Error starting background tracking: $e');
      }
    } else if (Platform.isAndroid && background == false) {
      background = true;
      debugPrint("バックグラウンド処理を開始しました。");

      try {
        // 位置情報の権限が許可されているかを確認
        await PermissionController.checkAndRequestPermissions();
      } catch (e) {
        print('Error starting background tracking: $e');
      }
    }
  } catch (e) {
    print('Error starting background tracking: $e');
    // 再試行するか、エラーを適切に処理
  }
}

Future<void> addGPStoDB(double la, double ln) async {
  //debugPrint("in addGPStoDB ${indexController.currentUser}");
  GpsDatabaseHelper db = GpsDatabaseHelper.instance;
  try {
      GpsData gpsData = GpsData(
          id: 0,
          team_name: team_name,
          event_code: event_code,
          lat: la,
          lon: ln,
          is_checkin: 0,
          created_at: DateTime.now().millisecondsSinceEpoch);
      var res = await db.insertGps(gpsData);
      debugPrint("バックグラウンドでのGPS保存：");
  } catch (err) {
    print("errr ready gps $err");
    return;
  }
}

Future<void> stopBackgroundTracking() async {
  try {
    if (Platform.isIOS && background == true) {
      background = false;
      debugPrint("バックグラウンド処理：停止しました。");
      await positionStream?.cancel();
      positionStream = null;
    } else if (Platform.isAndroid && background == true) {
      background = false;
      debugPrint("バックグラウンド処理：停止しました。");
      const platform = MethodChannel('location');
      try {
        await platform.invokeMethod('stopLocationService');
      } on PlatformException catch (e) {
        print("Failed to stop location service: '${e.message}'.");
      }
    }
  } catch(e){
    print('Error stopping background tracking: $e');
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  // This widget is the root of your application.
  late final LocationController _locationController;
  late final IndexController _indexController;
  late final DestinationController _destinationController;
  late final PermissionController _permissionController;
  Timer? _memoryCheckTimer;
  bool _isControllerInitialized = false;

  @override
  void initState() {
    super.initState();
    _initializeControllers();
    WidgetsBinding.instance.addObserver(this);
    //_startMemoryMonitoring();

    if (context.mounted) {
    //  _restoreGameAndInitialize();
    }

    // ウィジェットが構築された後に権限をチェック
    WidgetsBinding.instance.addPostFrameCallback((_) {
      PermissionController.checkAndRequestPermissions();
    });

    debugPrint("Start MyAppState...");
  }

  Future<void> _restoreGameAndInitialize() async {
    await restoreGame();
    // ここに他の初期化処理を追加できます
  }

  Future <void> _initializeControllers() async {

    while (!Get.isRegistered<LocationController>() ||
        !Get.isRegistered<IndexController>() ||
        !Get.isRegistered<DestinationController>() ||
        !Get.isRegistered<PermissionController>()) {
      await Future.delayed(const Duration(milliseconds: 100));
    }

    if (!_isControllerInitialized) {
      _locationController = Get.find<LocationController>();
      _indexController = Get.find<IndexController>();
      _destinationController = Get.find<DestinationController>();
      _permissionController = Get.find<PermissionController>();
      _isControllerInitialized = true;
    }

    /*
    while (true) {
      try {
        _locationController = Get.find<LocationController>();
        break; // DestinationControllerが見つかったらループを抜ける
      } catch (e) {
        // DestinationControllerがまだ利用可能でない場合は少し待ってから再試行
        await Future.delayed(const Duration(milliseconds: 100));
      }
    }
     */
    /*
    if (!Get.isRegistered<LocationController>()) {
      _locationController = Get.put(LocationController(), permanent: true);
    }
     */

    /*
    while (true) {
      try {
        _indexController = Get.find<IndexController>();
        break; // DestinationControllerが見つかったらループを抜ける
      } catch (e) {
        // DestinationControllerがまだ利用可能でない場合は少し待ってから再試行
        await Future.delayed(const Duration(milliseconds: 100));
      }
    }
     */
    /*
    if (!Get.isRegistered<IndexController>()) {
      _indexController = Get.put(IndexController(apiService: Get.find<ApiService>()), permanent: true);
    }
     */

    /*
    while (true) {
      try {
        _destinationController = Get.find<DestinationController>();
        break; // DestinationControllerが見つかったらループを抜ける
      } catch (e) {
        // DestinationControllerがまだ利用可能でない場合は少し待ってから再試行
        await Future.delayed(const Duration(milliseconds: 100));
      }
    }
     */
    /*
    if (!Get.isRegistered<DestinationController>()) {
      _destinationController =
          Get.put(DestinationController(), permanent: true);
    }
     */

    /*
    while (true) {
      try {
        _permissionController = Get.find<PermissionController>();
        break; // DestinationControllerが見つかったらループを抜ける
      } catch (e) {
        // DestinationControllerがまだ利用可能でない場合は少し待ってから再試行
        await Future.delayed(const Duration(milliseconds: 100));
      }
    }
     */
    /*
    if (!Get.isRegistered<PermissionController>()) {
      _permissionController = Get.put(PermissionController());
    }
     */
    // 他の必要なコントローラーの初期化


  }

  void _startMemoryMonitoring() {
    /*
    _memoryCheckTimer = Timer.periodic(const Duration(seconds: 10), (timer) {
      _checkMemoryUsage();
    });

     */
  }

  void _checkMemoryUsage() async {
    final memoryInfo = await _getMemoryInfo();
    //debugPrint('Current memory usage: ${memoryInfo['used']} MB');
    if (memoryInfo['used']! > 100) { // 100MB以上使用している場合
      _performMemoryCleanup();
    }
  }

  Future<Map<String, int>> _getMemoryInfo() async {
    // プラットフォーム固有のメモリ情報取得ロジックを実装
    // この例では仮の値を返しています
    return {'total': 1024, 'used': 512};
  }

  void _performMemoryCleanup() {
    /*
    debugPrint('Performing memory cleanup');
    // キャッシュのクリア

    Get.deleteAll(force: false);  // 永続的なコントローラーを除外してキャッシュをクリア
    imageCache.clear();
    imageCache.clearLiveImages();

    // 大きなオブジェクトの解放
    _clearLargeObjects();

    // 未使用のリソースの解放
    _releaseUnusedResources();

    // ガベージコレクションの促進
    _forceGarbageCollection();
    debugPrint('Performing memory cleanup');

     */
  }

  void _clearLargeObjects() {
    // 大きなリストやマップをクリア
    // 例: myLargeList.clear();
  }

  void _releaseUnusedResources() {
    // 使用していないストリームのクローズ
    // 例: myStream?.close();
  }

  void _forceGarbageCollection() {
    /*
    Timer(const Duration(seconds: 1), () {
      debugPrint('Forcing garbage collection');
      // ignore: dead_code
      bool didRun = false;
      assert(() {
        didRun = true;
        return true;
      }());
      if (didRun) {
        debugPrint('Garbage collection forced in debug mode');
      }
    });

     */
  }


/*
  void showPermissionRequiredDialog() {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('権限が必要です'),
          content: Text('このアプリは機能するために位置情報の権限が必要です。設定で権限を許可してください。'),
          actions: <Widget>[
            TextButton(
              child: Text('設定を開く'),
              onPressed: () {
                openAppSettings();
                Navigator.of(context).pop();
              },
            ),
            TextButton(
              child: Text('アプリを終了'),
              onPressed: () {
                // アプリを終了
                Navigator.of(context).pop();
                // よりクリーンな終了のために 'flutter_exit_app' のようなプラグインを使用することをお勧めします
                // 今回は単にすべてのルートをポップします
                Navigator.of(context).popUntil((route) => false);
              },
            ),
          ],
        );
      },
    );
  }

 */


  @override
  void dispose() {
    _isControllerInitialized = false;
    WidgetsBinding.instance.removeObserver(this);
    _memoryCheckTimer?.cancel();
    super.dispose();
  }

  // void saveGameState() async {
  //     DestinationController destinationController = Get.find<DestinationController>();
  //     SharedPreferences pref = await SharedPreferences.getInstance();
  //     pref.setBool("is_in_rog", destinationController.is_in_rog.value);
  //     pref.setBool("rogaining_counted", destinationController.rogaining_counted.value);
  // }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    try {
      if (!Get.isRegistered<IndexController>()) {
        _indexController = Get.find<IndexController>();
      }
      if (!Get.isRegistered<LocationController>()) {
        _locationController = Get.find<LocationController>();
      }
      if (!Get.isRegistered<DestinationController>()) {
        _destinationController = Get.find<DestinationController>();
      }

      switch (state) {
        case AppLifecycleState.resumed:
          if (Platform.isIOS) {
            MotionService.startMotionUpdates();
          }
          //await _onResumed();
          await _onResumed();
          break;
        case AppLifecycleState.inactive:

        // アプリが非アクティブになったときに発生します。
          await _onInactive();
          break;

        case AppLifecycleState.paused:
          MotionService.stopMotionUpdates();
        // バックグラウンドに移行したときの処理
        //locationController.resumePositionStream();
          await _onPaused();
          break;

        case AppLifecycleState.detached:
        // アプリが終了する直前に発生します。この状態では、アプリはメモリから解放される予定です。
        //locationController.resumePositionStream();
          await _onDetached();
          break;

        case AppLifecycleState.hidden:
        // Web用の特殊な状態で、モバイルアプリでは発生しません。
        //locationController.resumePositionStream();
          await _onHidden();
          break;
      }
    }catch(e){
      print('Error finding didChangeAppLifecycleState: $e');
      _initializeControllers();
    }
  }

  Future<void> _onResumed() async {
    debugPrint("==(Status Changed)==> RESUMED");
    try {
      if (!_isControllerInitialized) {
        await _initializeControllers();
      }

      await stopBackgroundTracking();
      _destinationController.restartGPS();

      if (Platform.isIOS && _destinationController.isRunningBackgroundGPS) {
        _locationController.resumePositionStream();
        await restoreGame();
        _destinationController.isRunningBackgroundGPS = false;
      } else if (Platform.isAndroid) {
        if (_destinationController.isRunningBackgroundGPS) {
          const platform = MethodChannel('location');
          await platform.invokeMethod('stopLocationService');
          _destinationController.isRunningBackgroundGPS = false;
          _destinationController.restartGPS();
        }
        _locationController.resumePositionStream();
        await restoreGame();
      }
    } catch(e) {
      print('Error in _onResumed: $e');
      // 必要に応じて再試行またはエラー処理
    }
  }

  Future<void> _onInactive() async {
    debugPrint("==(Status Changed)==> INACTIVE");
    if (Platform.isIOS && !_destinationController.isRunningBackgroundGPS) {
      debugPrint(" ==(Status Changed)==> INACTIVE. 非アクティブ処理。");
      _locationController.stopPositionStream();
      _destinationController.isRunningBackgroundGPS = true;
      await startBackgroundTracking();
    } else if (Platform.isAndroid && !_destinationController.isRunningBackgroundGPS) {
      // Android特有の処理があれば追加
      debugPrint(" ==(Status Changed)==> INACTIVE. 非アクティブ処理。");
    }else{
      debugPrint("==(Status Changed)==> INACTIVE　不明状態");
    }
    await saveGameState();
  }

  Future<void> _onPaused() async {
    debugPrint(" ==(Status Changed)==> PAUSED. バックグラウンド処理。");
    if (Platform.isAndroid && !_destinationController.isRunningBackgroundGPS) {
      debugPrint(" ==(Status Changed)==> PAUSED. Android バックグラウンド処理。");
      _locationController.stopPositionStream();
      const platform = MethodChannel('location');
      await platform.invokeMethod('startLocationService');
      _destinationController.isRunningBackgroundGPS = true;
    }
    await saveGameState();
  }

  Future<void> _onDetached() async {
    debugPrint(" ==(Status Changed)==> DETACHED アプリは終了します。");
    await saveGameState();
    // アプリ終了時の追加処理
  }


  Future<void> _onHidden() async {
    debugPrint(" ==(Status Changed)==> Hidden　アプリが隠れた");
    await saveGameState();
  }

  @override
  Widget build(BuildContext context) {

    return GetMaterialApp(
      translations: StringValues(),
      locale: const Locale('ja', 'JP'),
      //locale: const Locale('en', 'US'),
      fallbackLocale: const Locale('en', 'US'),
      title: 'ROGAINING',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
            seedColor: const Color.fromARGB(255, 36, 135, 221)),
        useMaterial3: true,
      ),
      debugShowCheckedModeBanner: false,
      defaultTransition: Transition.cupertino,
      opaqueRoute: Get.isOpaqueRouteDefault,
      popGesture: Get.isPopGestureEnable,
      transitionDuration: const Duration(milliseconds: 230),
      initialBinding: IndexBinding(), //HomeBinding(),
      initialRoute: AppPages.PERMISSION,
      getPages: AppPages.routes,
      enableLog: true,
    );
  }



}
