import 'dart:async';
import 'dart:io';
import 'package:absenkuv3/Bloc/CustomFunction.dart' as customFunction;
import 'package:absenkuv3/Repository/Model/PageModel/mButtonPage.dart';
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/absensiApi.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:absenkuv3/UI/Template/dialog/alertDialog.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:sn_progress_dialog/sn_progress_dialog.dart';
// import 'package:trust_location/trust_location.dart';

import '../CustomFunction.dart';
import '../NavigatorBloc.dart';

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

class TambahAbsenEvent extends AbsensiEvent {
  DataAbsensi dataAbsensi;
  TambahAbsenEvent(
      _context, GlobalKey<ScaffoldState> _scaffoldKey, this.dataAbsensi) {
    context = _context;
    scaffoldKey = _scaffoldKey;
  }
}

class CekAbsenEvent extends AbsensiEvent {
  CekAbsenEvent(BuildContext? _context) {
    context = _context;
  }
}

class LoadingEvent extends AbsensiEvent {
  LoadingEvent(BuildContext? _context) {
    context = _context;
  }
}

abstract class AbsensiState {
  AbsensiHariIniRespon? data;
  BasicRespon? basicRespon;
}

class AbsensiInitial extends AbsensiState {} // INITIAL STATE

class AbsensiLoading extends AbsensiState {} // LOADING STATE

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

class AbsensiFailure extends AbsensiState {
  final String errorMessage;
  AbsensiFailure(this.errorMessage);
} // FAILURE STATE

class AbsensiSuccess extends AbsensiState {
  final Set<Marker> markers;
  final Position? position;
  final Completer<GoogleMapController> controller;
  final AbsensiHariIniRespon dataAbsen;
  AbsensiSuccess(this.markers, this.position, this.controller, this.dataAbsen);
}

class KirimAbsenProgress extends AbsensiState {
  KirimAbsenProgress(AbsensiEvent event);
}

class AbsensiRespon extends AbsensiState {
  AbsensiRespon(AbsensiEvent event, BasicRespon _data) {
    Navigator.of(event.context!).pop();
    basicRespon = _data;
    showDialog(
      barrierDismissible: false,
      context: event.context!,
      builder: (BuildContext context) => AlertDialogCustom(
          data: basicRespon,
          onClick: () {
            BlocProvider.of<NavigatorBloc>(context)
                .add(NavigateRemoveToDashboard(context));
          }),
    );
  }
}

class AbsensiBloc extends Bloc<AbsensiEvent, AbsensiState> {
  Position? _latLng;
  final Set<Marker> _markers = {};
  Completer<GoogleMapController> _controller = Completer();
  // GoogleMapController? _controllerMap;

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

  AbsensiBloc(AbsensiState initialState) : super(initialState);

  @override
  Stream<AbsensiState> mapEventToState(AbsensiEvent event) async* {
    if (event is CekAbsenEvent) {
      MessagePageModel? messageData;
      PengaturanBahasa().messageData().then((value) => messageData = value);
      yield AbsensiLoading();

      // print("masuuk");
      var status = await Permission.location.status;

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

        if (permanent) {
          await sharedPreferences().setInitialMockStatus(true);

          if (await sharedPreferences().getInitialPermanentStatus() == false) {
            yield PeringatanState(
              messageData!.message!.gpsBelumDisetujui,
              'PermissionGPS',
            );
            await sharedPreferences().setInitialPermanentStatus(true);
          }

          // Optional: navigasi balik jika diperlukan
          // BlocProvider.of<NavigatorBloc>(event.context!).add(NavigatePop(event.context!));
        } else {
          PermissionStatus requestResult = await Permission.location.request();

          if (requestResult.isGranted) {
            debugPrint("Android Authorized: Permission Granted");
            BlocProvider.of<AbsensiBloc>(event.context!)
                .add(CekAbsenEvent(event.context));
          } else if (requestResult.isPermanentlyDenied) {
            await sharedPreferences().setInitialMockStatus(true);

            if (await sharedPreferences().getInitialPermanentStatus() ==
                false) {
              yield PeringatanState(
                messageData!.message!.gpsBelumDisetujui,
                'PermissionGPS',
              );
              await sharedPreferences().setInitialPermanentStatus(true);
            }
          } else {
            debugPrint("Permission Denied: $requestResult");
          }
        }
      }
      if (status.isGranted) {
        var status = await Permission.location.serviceStatus;
        if (status.isDisabled) {
          try {
            await Future.delayed(Duration(milliseconds: 600));
            BlocProvider.of<AbsensiBloc>(event.context!)
                .add(CekAbsenEvent(event.context));
          } catch (e) {
            yield AbsensiFailure(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;
          }
          print("status1 ${developerMode}");
          print("status2 ${!ServerInfo.bolehDevelopermod}");
          if (developerMode && !ServerInfo.bolehDevelopermod) {
            print("status3 ${developerMode}");
            print("status4 ${!ServerInfo.bolehDevelopermod}");
            yield PeringatanState(
                // "Harap mematikan developer mode untuk melakukan absensi",'developerMode');
                messageData!.message!.developerMode!,
                'developerMode');
            print(messageData!.message!.developerMode!);
            print('masuk sini');
          } else {
            print('status6');
            if (Platform.isAndroid) {
              // fake = await TrustLocation.isMockLocation;
              fake = await SecurityService.isLocationFake();
              print("INI FAKE ${fake}");
            }
            if (fake) {
              if (await sharedPreferences().getInitialMockStatus()) {
                //CEK FIRST RUN APP
                await Future.delayed(Duration(milliseconds: 600));
                BlocProvider.of<AbsensiBloc>(event.context!)
                    .add(CekAbsenEvent(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) {
                DataAbsensi data = DataAbsensi(
                    latitude: _latLng!.latitude.toString(),
                    longitude: _latLng!.longitude.toString());
                AbsensiHariIniRespon dataAbsen =
                    await AbsensiApi().absensiHariIni(data);
                if (dataAbsen.status!) {
                  yield AbsensiSuccess(
                      _markers, _latLng, _controller, dataAbsen);
                } else {
                  yield PeringatanState(dataAbsen.message, 'errorData');
                }
              } else {
                yield AbsensiFailure(messageData!.message!.gpsBelumSiap!);
              }
            }
          }
        }
      }
    } else if (event is LoadingEvent) {
      yield AbsensiInitial();
    } else if (event is TambahAbsenEvent) {
      PageButtonModel? button;
      PengaturanBahasa().button().then((value) => button = value);
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      BasicRespon basicRespon = await AbsensiApi().absensi(event.dataAbsensi);
      ProgressDialogDelayed.hide(pd);
      if (basicRespon.success!) {
        debugPrint(event.context.toString() + ' ---context');
        print("ini shift ${event.dataAbsensi.fleksible_jam_kerja}");
        if (event.dataAbsensi.fleksible_jam_kerja! ?? false) {
          customFunction.CustomPopUpShiftLepas.show(
              basicRespon.message, event.context, button!.button!.btnTutup,
              doublePop: false, isDismissible: false, closeCustom: () {
            BlocProvider.of<NavigatorBloc>(event.context!)
                .add(NavigateToAbsensiReplace(event.context!));
          });
        } else {
          customFunction.CustomPopUp.show(
              basicRespon.message, event.context, button!.button!.btnTutup,
              isDismissible: false);
          BlocProvider.of<AbsensiBloc>(event.context!)
              .add(CekAbsenEvent(event.context));
        }
      }
    }
  }
}
