import 'dart:async';
import 'dart:io';
import 'package:absenkuv3/Repository/Model/PageModel/mButtonPage.dart';
import 'package:absenkuv3/Repository/Model/PageModel/mMessagePage.dart';
import 'package:absenkuv3/Repository/Model/mLembur.dart';
import 'package:absenkuv3/Repository/Model/mSplashScreen.dart';
import 'package:absenkuv3/Bloc/CustomFunction.dart' as customFunction;
import 'package:absenkuv3/Repository/Service/lemburApi.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:absenkuv3/UI/Template/style.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 AbsensiLemburEvent {
  BuildContext? context;
  GlobalKey<ScaffoldState>? scaffoldKey;
}

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

class CekAbsenLemburEvent extends AbsensiLemburEvent {
  CekAbsenLemburEvent(BuildContext? _context) {
    context = _context;
  }
}

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

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

class AbsensiLemburInitial extends AbsensiLemburState {} // INITIAL STATE

class AbsensiLemburLoading extends AbsensiLemburState {} // LOADING STATE

class AbsensiLemburFailure extends AbsensiLemburState {
  final String errorMessage;
  AbsensiLemburFailure(this.errorMessage);
} // FAILURE STATE

class AbsensiLemburSuccess extends AbsensiLemburState {
  final Set<Marker> markers;
  final Position? position;
  final Completer<GoogleMapController> controller;
  final LemburHariIniRespon? dataAbsen;
  AbsensiLemburSuccess(
      this.markers, this.position, this.controller, this.dataAbsen);
}

class KirimAbsenLemburProgress extends AbsensiLemburState {
  KirimAbsenLemburProgress(AbsensiLemburEvent event);
}

class AbsensiLemburRespon extends AbsensiLemburState {
  AbsensiLemburRespon(AbsensiLemburEvent 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 AbsensiLemburBloc extends Bloc<AbsensiLemburEvent, AbsensiLemburState> {
  Position? _latLng;
  final Set<Marker> _markers = {};
  Completer<GoogleMapController> _controller = Completer();
  // GoogleMapController? _controllerMap;

  AbsensiLemburBloc(AbsensiLemburState initialState) : super(initialState);

  @override
  Stream<AbsensiLemburState> mapEventToState(AbsensiLemburEvent event) async* {
    if(event is CekAbsenLemburEvent){
      yield AbsensiLemburLoading();
      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<AbsensiLemburBloc>(event.context!)
              .add(CekAbsenLemburEvent(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<AbsensiLemburBloc>(event.context!)
                .add(CekAbsenLemburEvent(event.context));
          }
          catch(e){
            yield AbsensiLemburFailure(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<AbsensiLemburBloc>(event.context!)
                    .add(CekAbsenLemburEvent(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());
                LemburHariIniRespon? lemburHariIniRespon =
                await LemburApi().absensiLemburHariIni(data);
                yield AbsensiLemburSuccess(
                    _markers, _latLng, _controller, lemburHariIniRespon);
              } else {
                yield AbsensiLemburFailure(messageData!.message!.gpsBelumSiap!);
              }
            }
          }
        }
      }
    }
    /*else if (event is CekAbsenLemburEvent) {
      _markers.clear();
      yield AbsensiLemburLoading();
      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<AbsensiLemburBloc>(event.context)
                .add(CekAbsenLemburEvent(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());
            LemburHariIniRespon lemburHariIniRespon =
                await LemburApi().absensiLemburHariIni(data);
            yield AbsensiLemburSuccess(
                _markers, _latLng, _controller, lemburHariIniRespon);
          } else {
            yield AbsensiLemburFailure("GPS belum siap");
          }
        }
      } else if (serviceStatus.toString() == 'ServiceStatus.disabled') {
        Position position =
            await getCurrentPosition(desiredAccuracy: LocationAccuracy.best);
        await Future.delayed(Duration(milliseconds: 600));
        BlocProvider.of<AbsensiLemburBloc>(event.context)
            .add(CekAbsenLemburEvent(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<AbsensiLemburBloc>(event.context)
              .add(CekAbsenLemburEvent(event.context));
      }
      //
    }*/

    else if (event is TambahAbsenLemburEvent) {
      //TAMBAH ABSEN
      PageButtonModel? button;
      PengaturanBahasa().button().then((value) => button = value);
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      Future.delayed(Duration(seconds: 1));
      BasicRespon basicRespon = await LemburApi().absensiLembur(event.dataAbsensi);

      ProgressDialogDelayed.hide(pd);
      if (basicRespon.success!) {
        customFunction.CustomPopUp.show(basicRespon.message, event.context, button!.button!.btnTutup,
            isDismissible: false);
        BlocProvider.of<AbsensiLemburBloc>(event.context!)
            .add(CekAbsenLemburEvent(event.context));
      } else {
        customFunction.CustomPopUp.show(basicRespon.message, event.context, button!.button!.btnTutup,
            icon: Icon(
              Icons.warning,
              color: CustomStyle.color1,
              size: 50,
            ),
            color: CustomStyle.fontColorBlack);
      }
    }
  }

  /*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;
    }
  }*/
}
