import 'dart:async';
import 'dart:io';

import 'package:absenkuv3/Bloc/Patroli/PatroliBloc.dart';
import 'package:absenkuv3/Bloc/CustomFunction.dart';
import 'package:absenkuv3/Bloc/NavigatorBloc.dart';
import 'package:absenkuv3/Repository/Model/mChekpoint.dart';
import 'package:absenkuv3/Repository/Model/mFilter.dart';
import 'package:absenkuv3/Repository/Model/mSplashScreen.dart';
import 'package:absenkuv3/Repository/Service/patroliApi.dart';
import 'package:absenkuv3/Repository/Service/serviceInfo.dart';
import 'package:absenkuv3/Repository/sharedPreference.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/progress_dialog.dart';
// import 'package:trust_location/trust_location.dart';
import 'package:absenkuv3/Bloc/CustomFunction.dart' as customFunction;

abstract class AbsensiPatroliEvent {
  BuildContext? context;
  GlobalKey<ScaffoldState>? scaffoldKey;
}

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

class CekAbsenPatroliEvent extends AbsensiPatroliEvent {
  CekAbsenPatroliEvent(BuildContext? _context) {
    context = _context;
  }
}

abstract class AbsensiPatroliState {
  BasicRespon? basicRespon;
}

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

class AbsensiPatroliInitial extends AbsensiPatroliState {} // INITIAL STATE

class AbsensiPatroliLoading extends AbsensiPatroliState {} // LOADING STATE

class AbsensiPatroliFailure extends AbsensiPatroliState {
  final String errorMessage;
  AbsensiPatroliFailure(this.errorMessage);
}

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

class KirimAbsenPatroliProgress extends AbsensiPatroliState {
  KirimAbsenPatroliProgress(AbsensiPatroliEvent event);
}

class AbsensiPatroliRespon extends AbsensiPatroliState {
  AbsensiPatroliRespon(AbsensiPatroliEvent 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 AbsensiPatroliBloc
    extends Bloc<AbsensiPatroliEvent, AbsensiPatroliState> {
  Position? _latLng;
  final Set<Marker> _markers = {};
  Completer<GoogleMapController> _controller = Completer();

  AbsensiPatroliBloc(AbsensiPatroliState initialState)
      : super(initialState);

  @override
  Stream<AbsensiPatroliState> mapEventToState(
      AbsensiPatroliEvent event) async* {
    if (event is CekAbsenPatroliEvent) {
      yield AbsensiPatroliLoading();
      var status = await Permission.location.status;
      if (status.isDenied || status.isPermanentlyDenied) {
        //BELUM REQUEST ATAU DI DENY
        if (status.isPermanentlyDenied) {
          yield PeringatanState(
              "Anda belum menyetujui penggunaan GPS untuk absensi",
              'PermissionGPS');
        } else {
          await Permission.location.request();
          BlocProvider.of<AbsensiPatroliBloc>(event.context!)
              .add(CekAbsenPatroliEvent(event.context));
        }
      }
      if (status.isGranted) {
        var status = await Permission.location.serviceStatus;
        if (status.isDisabled) {
          try {
            await Future.delayed(Duration(milliseconds: 600));
            BlocProvider.of<AbsensiPatroliBloc>(event.context!)
                .add(CekAbsenPatroliEvent(event.context));
          } catch (e) {
            yield AbsensiPatroliFailure(
                "Harap menyalakan GPS untuk menggunakan fitur ini");
          }
        } 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(
                ServerInfo.messageDeveloperMode, '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<AbsensiPatroliBloc>(event.context!)
                    .add(CekAbsenPatroliEvent(event.context));
              } else
                yield PeringatanState(
                    "Anda terdeteksi menggunakan fake GPS", '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 PatroliApi().cekLokasi(data);
                yield AbsensiPatroliSuccess(
                    _markers, _latLng, _controller, cekLokasiRespon);
              } else {
                yield AbsensiPatroliFailure("GPS belum siap");
              }
            }
          }
        }
      }
    } else if (event is TambahAbsenPatroliEvent) {
      ProgressDialog pd = ProgressDialog(context: event.context);
      ProgressDialogDelayed.show(pd, isDismissible: false);
      BasicRespon basicRespon =
          await PatroliApi().tambahChekpoint(event.dataAbsensi);
      ProgressDialogDelayed.hide(pd);
      if (basicRespon.success!) {
        customFunction.CustomPopUp.show(basicRespon.message, event.context,'tutup',
            doublePop: true, isDismissible: false);
        BlocProvider.of<PatroliBloc>(event.context!).add(
            getListPatroliEvent(event.context,
                ModelFilter(dateRange: [DateTime.now(), DateTime.now()])));
      }
    }
  }
}
