import 'dart:async';
import 'dart:io';
import 'package:absenkuv3/Repository/Model/PageModel/mMessagePage.dart';
import 'package:absenkuv3/Repository/Model/mAbsensi.dart';
import 'package:absenkuv3/Repository/Model/mSplashScreen.dart';
import 'package:absenkuv3/Repository/Service/serviceInfo.dart';
import 'package:absenkuv3/Repository/sharedPreference.dart';
import 'package:absenkuv3/Setting/PengaturanBahasa.dart';
import 'package:absenkuv3/Setting/security_service.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:flutter_easy_permission/easy_permissions.dart';
// import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
// import 'package:trust_location/trust_location.dart';

//Event
abstract class MapsEvent {
  BuildContext? context;
  GlobalKey<ScaffoldState>? scaffoldKey;
}

class GetMapsEvent extends MapsEvent {
  GetMapsEvent(BuildContext? _context) {
    context = _context;
  }
}

class SetMapsEvent extends MapsEvent {
  Position? latLng;
  Set<Marker>? markers;
  SetMapsEvent(BuildContext? _context, Position _latLng, Set<Marker> _markers) {
    context = _context;
    latLng = _latLng;
    markers = _markers;
  }
}

abstract class MapsState {}

class MapsInitial extends MapsState {} // INITIAL STATE

class MapsLoading extends MapsState {} // LOADING STATE

class PeringatanState extends MapsState {
  String jenisPeringatan;
  String? message;
  PeringatanState(this.message, this.jenisPeringatan);
}

class MapsFailure extends MapsState {
  final String errorMessage;
  MapsFailure(this.errorMessage);
} // FAILURE STATE

class MapsSuccess extends MapsState {
  final Set<Marker> markers;
  final Position? position;
  final Completer<GoogleMapController> controller;
  MapsSuccess(this.markers, this.position, this.controller);
}

class MapsBloc extends Bloc<MapsEvent, MapsState> {
  Position? _latLng;
  final Set<Marker> _markers = {};
  Completer<GoogleMapController> _controller = Completer();

  // var permissions = [Permissions.ACCESS_COARSE_LOCATION,Permissions.ACCESS_FINE_LOCATION];
  // var permissionGroup = [PermissionGroup.Location];
  bool permanent = false;

  MapsBloc(MapsState initialState) : super(initialState);

  @override
  Stream<MapsState> mapEventToState(MapsEvent event) async* {
    if (event is GetMapsEvent) {
      MessagePageModel? messageData;
      PengaturanBahasa().messageData().then((value) => messageData = value);
      yield MapsLoading();
      var status = await Permission.location.status;
      if (status.isDenied || status.isPermanentlyDenied) {
        bool permanent = await Permission.location.status.isPermanentlyDenied;

        if (permanent) {
          if (await sharedPreferences().getInitialPermanentStatus() == false) {
            yield PeringatanState(
                messageData!.message!.gpsBelumDisetujui, 'PermissionGPS');
            await sharedPreferences().setInitialPermanentStatus(true);
          }
        } else {
          // Request permission
          final requestResult = await Permission.location.request();

          if (requestResult.isGranted) {
            // Permission granted
            BlocProvider.of<MapsBloc>(event.context!)
                .add(GetMapsEvent(event.context));
          } else if (requestResult.isPermanentlyDenied) {
            // Update status if permanently denied after request
            await sharedPreferences().setInitialMockStatus(true);
            await sharedPreferences().setInitialPermanentStatus(true);

            yield PeringatanState(
                messageData!.message!.gpsBelumDisetujui, 'PermissionGPS');
          }
        }
      }
      if (status.isGranted) {
        var status = await Permission.location.serviceStatus;
        if (status.isDisabled) {
          try {
            await Future.delayed(Duration(milliseconds: 600));
            BlocProvider.of<MapsBloc>(event.context!)
                .add(GetMapsEvent(event.context));
          } catch (e) {
            yield MapsFailure(messageData!.message!.gpsBelumDinyalakan!);
          }
        } else {
          bool fake = false;
          bool developerMode = false;

          if (Platform.isAndroid) {
            try {
              developerMode = await SecurityService.isDeveloperModeEnabled();
            } on PlatformException {
              developerMode = true;
            }
          } else {
            developerMode = false;
          }
          if (developerMode && !ServerInfo.bolehDevelopermod) {
            yield PeringatanState(
                messageData!.message!.developerMode!, 'developerMode');
          } else {
            if (Platform.isAndroid) {
              // fake = await TrustLocation.isMockLocation;
            }
            if (fake) {
              if (await sharedPreferences().getInitialMockStatus()) {
                //CEK FIRST RUN APP
                await Future.delayed(Duration(milliseconds: 600));
                BlocProvider.of<MapsBloc>(event.context!)
                    .add(GetMapsEvent(event.context));
              } else
                yield PeringatanState(
                    messageData!.message!.terdeteksiMock, 'fakeGPS');
            } else {
              await sharedPreferences().setInitialMockStatus(false);
              var currentLocation = await Geolocator.getCurrentPosition(
                  desiredAccuracy: LocationAccuracy.best);
              _latLng = currentLocation;
              _markers.clear();
              _markers.add(
                Marker(
                  markerId: MarkerId(
                      "${currentLocation.latitude}, ${currentLocation.longitude}"),
                  icon: BitmapDescriptor.defaultMarker,
                  position: LatLng(
                      currentLocation.latitude, currentLocation.longitude),
                ),
              );
              if (_latLng != null) {
                yield MapsSuccess(_markers, _latLng, _controller);
              } else {
                yield MapsFailure(messageData!.message!.gpsBelumSiap!);
              }
            }
          }
        }
      }
    } else if (event is SetMapsEvent) {
      MessagePageModel? messageData;
      PengaturanBahasa().messageData().then((value) => messageData = value);
      yield MapsLoading();
      PermissionStatus status = await Permission.location.status;

      if (status.isDenied || status.isPermanentlyDenied) {
        bool permanent = status.isPermanentlyDenied;

        if (permanent) {
          // Simpan status mock jika belum disimpan
          await sharedPreferences().setInitialMockStatus(true);

          if (await sharedPreferences().getInitialPermanentStatus() == false) {
            yield PeringatanState(
              messageData!.message!.gpsBelumDisetujui,
              'PermissionGPS',
            );
            await sharedPreferences().setInitialPermanentStatus(true);
          }
        } else {
          // Minta izin lokasi
          PermissionStatus requestResult = await Permission.location.request();

          if (requestResult.isGranted) {
            BlocProvider.of<MapsBloc>(event.context!)
                .add(GetMapsEvent(event.context));
          } else if (requestResult.isPermanentlyDenied) {
            await sharedPreferences().setInitialMockStatus(true);
            await sharedPreferences().setInitialPermanentStatus(true);

            yield PeringatanState(
              messageData!.message!.gpsBelumDisetujui,
              'PermissionGPS',
            );
          }
        }
      }
      if (status.isGranted) {
        var status = await Permission.location.serviceStatus;
        if (status.isDisabled) {
          try {
            await Future.delayed(Duration(milliseconds: 600));
            BlocProvider.of<MapsBloc>(event.context!)
                .add(GetMapsEvent(event.context));
          } catch (e) {
            yield MapsFailure(messageData!.message!.gpsBelumDinyalakan!);
          }
        } else {
          bool fake = false;
          bool developerMode = false;

          if (Platform.isAndroid) {
            try {
              developerMode = await SecurityService.isDeveloperModeEnabled();
            } on PlatformException {
              developerMode = true;
            }
          } else {
            developerMode = false;
          }
          if (developerMode && !ServerInfo.bolehDevelopermod) {
            yield PeringatanState(
                messageData!.message!.developerMode!, 'developerMode');
          } else {
            if (Platform.isAndroid) {
              // fake = await TrustLocation.isMockLocation;
            }
            if (fake) {
              if (await sharedPreferences().getInitialMockStatus()) {
                //CEK FIRST RUN APP
                await Future.delayed(Duration(milliseconds: 600));
                BlocProvider.of<MapsBloc>(event.context!)
                    .add(GetMapsEvent(event.context));
              } else
                yield PeringatanState(
                    messageData!.message!.terdeteksiMock, 'fakeGPS');
            } else {
              await sharedPreferences().setInitialMockStatus(false);
              var currentLocation = await Geolocator.getCurrentPosition(
                  desiredAccuracy: LocationAccuracy.best);
              _latLng = event.latLng;
              _markers.clear();
              _markers.add(
                Marker(
                  markerId: MarkerId(
                      "${event.latLng!.latitude}, ${event.latLng!.longitude}"),
                  icon: BitmapDescriptor.defaultMarker,
                  position:
                      LatLng(event.latLng!.latitude, event.latLng!.longitude),
                ),
              );
              if (_latLng != null) {
                yield MapsSuccess(_markers, _latLng, _controller);
              } else {
                yield MapsFailure(messageData!.message!.gpsBelumSiap!);
              }
            }
          }
        }
      }
      // yield MapsSuccess(event.markers!, event.latLng, _controller);
    }
  }
}
