import 'dart:async';
import 'dart:io';
import 'package:absenkuv3/Bloc/Aktivitas/DetailAktivitasBloc.dart';
import 'package:absenkuv3/Bloc/CustomFunction.dart' as customFunction;
import 'package:absenkuv3/Bloc/Aktivitas/AktivitasBloc.dart';
import 'package:absenkuv3/Repository/Model/PageModel/mButtonPage.dart';
import 'package:absenkuv3/Repository/Model/PageModel/mMessagePage.dart';
import 'package:absenkuv3/Repository/Model/mAktivitas.dart';
import 'package:absenkuv3/Repository/Model/mFilter.dart';
import 'package:absenkuv3/Repository/Model/mLembur.dart';
import 'package:absenkuv3/Repository/Model/mSplashScreen.dart';
import 'package:absenkuv3/Repository/Service/aktivitasApi.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_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 AbsensiAktivitasEvent {
  BuildContext? context;
  BuildContext? contextDetail;
  GlobalKey<ScaffoldState>? scaffoldKey;
}

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

class EditAbsenAktivitasEvent extends AbsensiAktivitasEvent {
  DataAbsensi dataAbsensi;
  EditAbsenAktivitasEvent(_context, _contextDetail,
      GlobalKey<ScaffoldState> _scaffoldKey, this.dataAbsensi) {
    context = _context;
    contextDetail = _contextDetail;
    scaffoldKey = _scaffoldKey;
  }
}

class CekAbsenAktivitasEvent extends AbsensiAktivitasEvent {
  CekAbsenAktivitasEvent(BuildContext? _context) {
    context = _context;
  }
}

//State
abstract class AbsensiAktivitasState {
  LemburHariIniRespon? data;
  BasicRespon? basicRespon;
}

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

class AbsensiAktivitasInitial extends AbsensiAktivitasState {} // INITIAL STATE

class AbsensiAktivitasLoading extends AbsensiAktivitasState {} // LOADING STATE

class AbsensiAktivitasFailure extends AbsensiAktivitasState {
  final String errorMessage;
  AbsensiAktivitasFailure(this.errorMessage);
} // FAILURE STATE

class AbsensiAktivitasSuccess extends AbsensiAktivitasState {
  final Set<Marker> markers;
  final Position? position;
  final Completer<GoogleMapController> controller;
  final CekLokasiRespon? cekLokasiRespon;
  AbsensiAktivitasSuccess(
      this.markers, this.position, this.controller, this.cekLokasiRespon);
}

class KirimAbsenAktivitasProgress extends AbsensiAktivitasState {
  KirimAbsenAktivitasProgress(AbsensiAktivitasEvent event);
}

class AbsensiAktivitasRespon extends AbsensiAktivitasState {
  AbsensiAktivitasRespon(AbsensiAktivitasEvent event, BasicRespon _data) {
    // print("absensi success");
    // ProgressDialogDelayed.hide(event.context);
    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 AbsensiAktivitasBloc
    extends Bloc<AbsensiAktivitasEvent, AbsensiAktivitasState> {
  Position? _latLng;
  final Set<Marker> _markers = {};
  Completer<GoogleMapController> _controller = Completer();
  // GoogleMapController? _controllerMap;

  AbsensiAktivitasBloc(AbsensiAktivitasState initialState)
      : super(initialState);

  @override
  Stream<AbsensiAktivitasState> mapEventToState(
      AbsensiAktivitasEvent event) async* {
    if (event is CekAbsenAktivitasEvent) {
      yield AbsensiAktivitasLoading();
      MessagePageModel? messageData;
      PengaturanBahasa().messageData().then((value) => messageData = value);
      var status = await Permission.location.status;
      if (status.isDenied || status.isPermanentlyDenied) {
        //BELUM REQUEST ATAU DI DENY
        if (status.isPermanentlyDenied) {
          yield PeringatanState(
              messageData!.message!.gpsBelumDisetujui!, 'PermissionGPS');
        } else {
          await Permission.location.request();
          BlocProvider.of<AbsensiAktivitasBloc>(event.context!)
              .add(CekAbsenAktivitasEvent(event.context));
        }
      }
      if (status.isGranted) {
        var status = await Permission.location.serviceStatus;
        if (status.isDisabled) {
          try {
            // Position position =
            // await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.best);
            await Future.delayed(Duration(milliseconds: 600));
            BlocProvider.of<AbsensiAktivitasBloc>(event.context!)
                .add(CekAbsenAktivitasEvent(event.context));
          } catch (e) {
            yield AbsensiAktivitasFailure(
                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<AbsensiAktivitasBloc>(event.context!)
                    .add(CekAbsenAktivitasEvent(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());
                CekLokasiRespon? cekLokasiRespon =
                    await ActivitasApi().cekLokasi(data);
                yield AbsensiAktivitasSuccess(
                    _markers, _latLng, _controller, cekLokasiRespon);
              } else {
                yield AbsensiAktivitasFailure(
                    messageData!.message!.gpsBelumSiap!);
              }
            }
          }
        }
      }
    }
    /*if (event is CekAbsenAktivitasEvent) {
      _markers.clear();
      yield AbsensiAktivitasLoading();
      var serviceStatus = await LocationPermissions().checkServiceStatus();
      //
      if (await checkLocationPermission() &&
          serviceStatus.toString() != 'ServiceStatus.disabled') {
        //CEK PERMISSION LOCATION
        bool fake = false;
        if (Platform.isAndroid) {
          fake = await TrustLocation.isMockLocation;
        }
        if (fake) {
          //CEK FAKE GPS
          print(
              'SHARED PREF MOCK : ${await sharedPreferences().getInitialMockStatus()}');
          if (await sharedPreferences().getInitialMockStatus()) {
            //CEK FIRST RUN APP
            await Future.delayed(Duration(milliseconds: 600));
            BlocProvider.of<AbsensiAktivitasBloc>(event.context)
                .add(CekAbsenAktivitasEvent(event.context));
          } else
            yield PeringatanState(
                "Anda terdeteksi menggunakan fake GPS", 'fakeGPS');
        } else {
          await sharedPreferences().setInitialMockStatus(false);
          var currentLocation =
              await getCurrentPosition(desiredAccuracy: LocationAccuracy.best);
          _latLng = currentLocation;
          _markers.add(
            Marker(
              markerId: MarkerId(
                  "${currentLocation.latitude}, ${currentLocation.longitude}"),
              icon: BitmapDescriptor.defaultMarker,
              position:
                  LatLng(currentLocation.latitude, currentLocation.longitude),
            ),
          );

          if (_latLng != null) {
            LoginRespon login = await sharedPreferences().getUserData();
            String _idKaryawan = login.dataLogin.idKaryawan;
            String _idCompany = login.dataLogin.idCompany;
            DataAbsensi data = DataAbsensi(
                idKaryawan: _idKaryawan,
                idCompany: _idCompany,
                latitude: _latLng.latitude.toString(),
                longitude: _latLng.longitude.toString());
            CekLokasiRespon cekLokasiRespon =
                await ActivitasApi().cekLokasi(data);
            yield AbsensiAktivitasSuccess(
                _markers, _latLng, _controller, cekLokasiRespon);
          } else {
            yield AbsensiAktivitasFailure("GPS belum siap");
          }
        }
      } else if (serviceStatus.toString() == 'ServiceStatus.disabled') {
        Position position =
            await getCurrentPosition(desiredAccuracy: LocationAccuracy.best);
        await Future.delayed(Duration(milliseconds: 600));
        BlocProvider.of<AbsensiAktivitasBloc>(event.context)
            .add(CekAbsenAktivitasEvent(event.context));
      } else {
        PermissionStatus permission =
            await LocationPermissions().requestPermissions();
        await Future.delayed(Duration(milliseconds: 500));
        if (permission.toString() == 'PermissionStatus.denied')
          yield PeringatanState(
              "Anda belum menyetujui penggunaan GPS untuk absensi",
              'PermissionGPS');
        else
          BlocProvider.of<AbsensiAktivitasBloc>(event.context)
              .add(CekAbsenAktivitasEvent(event.context));
      }
      //

    } */
    else if (event is TambahAbsenAktivitasEvent) {
      //TAMBAH ABSEN
      PageButtonModel? button;
      PengaturanBahasa().button().then((value) => button = value);
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      BasicRespon basicRespon =
          await ActivitasApi().tambahAktivitas(event.dataAbsensi);
      ProgressDialogDelayed.hide(pd);
      if (basicRespon.success!) {
        customFunction.CustomPopUp.show(
            basicRespon.message, event.context, button!.button!.btnTutup,
            doublePop: true, isDismissible: false);
        BlocProvider.of<AktivitasBloc>(event.context!).add(
            getListAktivitasEvent(event.context,
                ModelFilter(dateRange: [DateTime.now(), DateTime.now()])));
      }
    } else if (event is EditAbsenAktivitasEvent) {
      //TAMBAH ABSEN
      PageButtonModel? button;
      PengaturanBahasa().button().then((value) => button = value);
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      BasicRespon basicRespon =
          await ActivitasApi().editAktivitas(event.dataAbsensi);
      ProgressDialogDelayed.hide(pd);
      if (basicRespon.success!) {
        customFunction.CustomPopUp.show(
            basicRespon.message, event.context, button!.button!.btnTutup,
            doublePop: true, isDismissible: false);
        Future.delayed(Duration(milliseconds: 600)).then((value) {
          BlocProvider.of<DetailAktivitasBloc>(event.contextDetail!)
              .add(GetDetailAktivitas(event.dataAbsensi.idAktivitas!));
        });
      }
    }
  }

  /*Future<bool> checkLocationPermission() async {
    PermissionStatus permissionStatusWhenInUse = await LocationPermissions()
        .checkPermissionStatus(
            level: LocationPermissionLevel.locationWhenInUse);
    PermissionStatus permissionStatusAlways = await LocationPermissions()
        .checkPermissionStatus(level: LocationPermissionLevel.locationAlways);
    PermissionStatus permissionStatus = await LocationPermissions()
        .checkPermissionStatus(level: LocationPermissionLevel.location);
    if (permissionStatusWhenInUse.toString() == 'PermissionStatus.denied' &&
        permissionStatusAlways.toString() == 'PermissionStatus.denied' &&
        permissionStatus.toString() == 'PermissionStatus.denied') {
      return false;
    } else {
      return true;
    }
  }*/
}
