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

import 'package:absenkuv3/Bloc/AuthBloc.dart';
import 'package:absenkuv3/Bloc/Patroli/AbsensiPatroliBloc.dart';
import 'package:absenkuv3/Bloc/NavigatorBloc.dart';
import 'package:absenkuv3/Repository/Model/PageModel/mSosPage.dart';
import 'package:absenkuv3/Repository/Model/mChekpoint.dart';
import 'package:absenkuv3/Repository/Model/mLogin.dart';
import 'package:absenkuv3/Setting/PengaturanBahasa.dart';
import 'package:absenkuv3/Setting/value_image.dart';
import 'package:absenkuv3/UI/Modul/Absensi/KomponenAbsensi.dart';
import 'package:absenkuv3/UI/Modul/Patroli/KomponenPatroli.dart';
import 'package:absenkuv3/UI/Template/Camera/Bloc/CameraBloc.dart';
import 'package:absenkuv3/UI/Template/Camera/Model/CameraModel.dart';
import 'package:absenkuv3/UI/Template/Camera/UI/HalamanCamera.dart';
import 'package:absenkuv3/UI/Template/CameraX/Model/CameraXRespon.dart';
import 'package:absenkuv3/UI/Template/style.dart';
import 'package:absenkuv3/UI/Template/templateButton.dart';
import 'package:absenkuv3/UI/Template/templateForm.dart';
import 'package:absenkuv3/UI/Template/templateIconInformation.dart';
import 'package:app_settings/app_settings.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:math' as math;

class HalamanTambahPatroli extends StatefulWidget {
  final JadwalChekpoint? jadwalChekpoint;
  const HalamanTambahPatroli({Key? key, this.jadwalChekpoint})
      : super(key: key);
  @override
  _HalamanTambahPatroli createState() => _HalamanTambahPatroli();
}

class _HalamanTambahPatroli extends State<HalamanTambahPatroli>
    with WidgetsBindingObserver {
  GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  CameraModel? cameraModel;
  TextEditingController keterangan = new TextEditingController();
  CekLokasiRespon? dataRespon;
  String? jenisPeringatan;
  bool lifeCycleStateInit = true;
  static const MethodChannel methodChannel = MethodChannel('absenku/camerax');
  static const EventChannel eventChannel =
      EventChannel('absenku/camerax/report');
  String _reportStatus = ' {"foto":"","matrix":""}';
  String? foto = "";
  String? matrix = "";
  var registrasi = false;
  Position? position;
  String? kamera2;
  String? gudang;
  DateTime now = DateTime.now();
  // String? formattedTime = DateFormat.jm().format(now);           //5:08 PM

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    gudang = ModalRoute.of(context)?.settings.arguments as String?;
    if (gudang != null) {
      print('The value of gudang is: $gudang');
    }
  }

  @override
  void initState() {
    WidgetsBinding.instance!.addObserver(this);
    BlocProvider.of<AbsensiPatroliBloc>(context)
        .add(CekAbsenPatroliEvent(context));
    super.initState();
  }

  void didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state == AppLifecycleState.resumed && lifeCycleStateInit) {
      BlocProvider.of<AbsensiPatroliBloc>(context)
          .add(CekAbsenPatroliEvent(context));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      body: BlocConsumer<AbsensiPatroliBloc, AbsensiPatroliState>(
          listener: (context, state) {
        if (state is PeringatanState) {
          jenisPeringatan = state.jenisPeringatan;
          popUpPeringatan(state.message, context);
        }
      }, builder: (context, state) {
        Set<Marker> _markers = {};
        Completer<GoogleMapController> _controller = Completer();
        CameraPosition _initPosition =
            CameraPosition(target: LatLng(-6.9932, 110.4203));
        if (state is AbsensiPatroliLoading) {
          return Container(
            height: double.infinity,
            width: double.infinity,
            child: Center(
                child: CircularProgressIndicator(
              strokeWidth: 8,
            )),
          );
        } else if (state is AbsensiPatroliFailure) {
          return Container(
            height: double.infinity,
            width: double.infinity,
            decoration: CustomStyle.boxDecoration,
            child: Center(
              child: Text(state.errorMessage),
            ),
          );
        } else if (state is AbsensiPatroliSuccess) {
          animateCamera(_controller, state.position!);
          _markers = state.markers;
          dataRespon = state.cekLokasiRespon;
          return FutureBuilder<PageSosModel>(
            future: PengaturanBahasa().sos(),
            builder: (BuildContext context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                return Stack(
                  children: [
                    Container(
                      height: double.infinity - 30,
                      width: double.infinity,
                      child: GoogleMap(
                        myLocationButtonEnabled: true,
                        compassEnabled: true,
                        zoomControlsEnabled: false,
                        initialCameraPosition: _initPosition,
                        mapType: MapType.normal,
                        onMapCreated: (GoogleMapController controllers) {
                          _controller.complete(controllers);
                        },
                        markers: _markers,
                      ),
                    ),
                    Align(
                      alignment: Alignment.topCenter,
                      child: Padding(
                        padding: const EdgeInsets.fromLTRB(20, 40, 20, 0),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            TombolIcon(
                              icon: Icons.keyboard_arrow_left,
                              onClick: () =>
                                  BlocProvider.of<NavigatorBloc>(context)
                                      .add(NavigateRemoveToDashboard(context)),
                            ),
                            TombolIcon(
                              icon: Icons.refresh,
                              onClick: () =>
                                  BlocProvider.of<AbsensiPatroliBloc>(context)
                                      .add(CekAbsenPatroliEvent(context)),
                            ),
                          ],
                        ),
                      ),
                    ),
                    Align(
                      alignment: Alignment.bottomCenter,
                      child: Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 0),
                        child: Container(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: [
                              SizedBox(
                                height: 19,
                              ),
                              Container(
                                width: double.infinity,
                                decoration: CustomStyle.boxDecoration2,
                                child: Padding(
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 0, vertical: 8),
                                  child: Column(
                                    children: [
                                      Container(
                                        decoration: CustomStyle.boxDecoration,
                                        margin: const EdgeInsets.all(16.0),
                                        padding: const EdgeInsets.symmetric(
                                            horizontal: 0, vertical: 12),
                                        child: Column(
                                          children: [
                                            IconInformation(
                                              icon: ValueImage.iconLokasi,
                                              title: snapshot.data!.menuSos!.data!.lokasi.toString(),
                                              subtitle:
                                                  "${gudang}\n${dataRespon!.cekLokasi!.ketLokasi}",
                                              sizeIcon: 33,
                                            ),
                                            Divider(),
                                            IconInformation(
                                              icon: ValueImage.iconRadius,
                                              title: snapshot.data!.menuSos!.data!.akurasi.toString(),
                                              subtitle:
                                                  '${state.position!.accuracy.round().toString()} Meter',
                                              sizeIcon: 29,
                                            ),
                                          ],
                                        ),
                                      ),
                                      Container(
                                        width: double.infinity,
                                        child: Padding(
                                          padding: const EdgeInsets.all(16.0),
                                          child: Row(
                                            children: [
                                              Container(
                                                child: BlocBuilder<AuthBloc,
                                                    LoginRespon>(
                                                  builder: (BuildContext
                                                          context,
                                                      LoginRespon loginRespon) {
                                                    return Expanded(
                                                      child:
                                                          buttonTambahChekpoint(
                                                        mulai: true,
                                                        enable: true,
                                                        label: snapshot.data!.menuSos!.button!.btnPatroli.toString(),
                                                        onClick: () async {
                                                          String? kamera =
                                                              loginRespon
                                                                  .dataLogin!
                                                                  .kamera;
                                                          if (kamera == '2') {
                                                            if (Platform
                                                                .isIOS) {
                                                              kamera = '1';
                                                            }
                                                          }
                                                          var status =
                                                              await Permission
                                                                  .camera
                                                                  .status;
                                                          if (status.isDenied ||
                                                              status
                                                                  .isPermanentlyDenied) {
                                                            if (status
                                                                .isPermanentlyDenied) {
                                                              jenisPeringatan =
                                                                  "PermissionGPS";
                                                              popUpPeringatan(
                                                                  "Anda belum menyetujui penggunaan Camera untuk absensi",
                                                                  context);
                                                            } else {
                                                              await Permission
                                                                  .camera
                                                                  .request();
                                                            }
                                                          } else {
                                                            lifeCycleStateInit =
                                                                false;
                                                            if (kamera == '1')
                                                              cameraModel = await Navigator.push<
                                                                      CameraModel>(
                                                                  context,
                                                                  MaterialPageRoute(
                                                                      builder: (_) =>
                                                                          BlocProvider(
                                                                            create: (BuildContext context) =>
                                                                                CameraBloc(InitializeCameraProgress()),
                                                                            child:
                                                                                CameraApp(
                                                                              "Chekpoint",
                                                                              false,
                                                                              changeCamera: true,
                                                                            ),
                                                                          )));
                                                            else if (kamera ==
                                                                '2') {
                                                              cameraModel =
                                                                  await routeCameraX(
                                                                      state
                                                                          .position,
                                                                      kamera!,snapshot.data!.menuSos);
                                                            } else {
                                                              XFile?
                                                                  pickedFile =
                                                                  await ImagePicker().pickImage(
                                                                      source: ImageSource
                                                                          .camera,
                                                                      imageQuality:
                                                                          75,
                                                                      maxWidth:
                                                                          400);
                                                              if (pickedFile !=
                                                                  null)
                                                                cameraModel = CameraModel(
                                                                    base64Encode(
                                                                        File(pickedFile.path)
                                                                            .readAsBytesSync()),
                                                                    pickedFile
                                                                        .path);
                                                            }
                                                            if (cameraModel !=
                                                                null)
                                                              openDialog(
                                                                  state
                                                                      .position,
                                                                  context,
                                                                  snapshot.data!.menuSos,
                                                                  rotate: kamera ==
                                                                              '1' &&
                                                                          cameraModel!.cameraId ==
                                                                              1
                                                                      ? true
                                                                      : false);
                                                          }
                                                        },
                                                      ),
                                                    );
                                                  },
                                                ),
                                              ),
                                            ],
                                          ),
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    )
                  ],
                );
              } else {
                return Container();
              }
            },
          );
        } else {
          return Container();
        }
      }),
    );
  }

  Future<void> animateCamera(Completer<GoogleMapController> _controller,
      Position currentLocation) async {
    final GoogleMapController controller = await _controller.future;
    CameraPosition _current = CameraPosition(
        target: LatLng(currentLocation.latitude, currentLocation.longitude),
        zoom: 17.151926040649414);
    controller.animateCamera(CameraUpdate.newCameraPosition(_current));
  }

  openDialog(Position? position, _context, MenuSos? rekasional,{bool rotate = true}) {
    final double mirror = math.pi;
    keterangan.text = '';
    showDialog(
        context: _context,
        builder: (BuildContext context) {
          return Form(
            key: formKey,
            child: AlertDialog(
              shape: RoundedRectangleBorder(
                  borderRadius:
                      BorderRadius.all(Radius.circular(CustomStyle.boxRadius))),
              content: SingleChildScrollView(
                reverse: true,
                child: Column(
                  children: <Widget>[
                    Column(
                      children: [
                        rotate
                            ? Transform(
                                alignment: Alignment.center,
                                child: Image.file(File(cameraModel!.path)),
                                transform: Matrix4.rotationY(mirror))
                            : Image.file(File(cameraModel!.path)),
                        SizedBox(
                          height: 12,
                        ),
                        TemplateForm(
                          formHeight: 56,
                          adaValidasi: true,
                          controller: keterangan,
                          color: Colors.grey[600],
                          titleText: rekasional!.data!.keterangan.toString(),
                          radius: CustomStyle.formRadius,
                          hintText: rekasional!.data!.keterangan.toString(),
                        ),
                      ],
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        TemplateButton(
                          onClick: () => BlocProvider.of<NavigatorBloc>(context)
                              .add(NavigatePop(context)),
                          label: rekasional.button!.btnCancle.toString(),
                          color: Colors.transparent,
                          contentColor: CustomStyle.color1,
                          fontSize: CustomStyle.fontSizeNormal,
                          bold: true,
                        ),
                        TemplateButton(
                          onClick: () {
                            if (formKey.currentState!.validate()) {
                              BlocProvider.of<NavigatorBloc>(_context)
                                  .add(NavigatePop(_context));
                              BlocProvider.of<AbsensiPatroliBloc>(_context).add(
                                  TambahAbsenPatroliEvent(
                                      _context,
                                      scaffoldKey,
                                      DataAbsensi(
                                          lokasiAbsen:
                                              dataRespon!.cekLokasi!.ketLokasi,
                                          latitude:
                                              position!.latitude.toString(),
                                          longitude:
                                              position.longitude.toString(),
                                          keteranganAbsen: keterangan.text,
                                          qr: gudang,
                                          minAbsen: widget
                                              .jadwalChekpoint!.minAbsen
                                              .toString(),
                                          maxAbsen: widget
                                              .jadwalChekpoint!.maxAbsen!
                                              .toString(),
                                          nmJadwal:
                                              widget.jadwalChekpoint!.nmJadwal,
                                          foto: cameraModel!.base64)));
                            }
                          },
                          label: rekasional.button!.btnSubmit.toString(),
                          color: Colors.transparent,
                          contentColor: CustomStyle.color1,
                          fontSize: CustomStyle.fontSizeNormal,
                          bold: true,
                        )
                      ],
                    )
                  ],
                ),
              ),
            ),
          );
        });
  }

  popUpPeringatan(String message, _context) {
    showDialog(
        barrierDismissible: false,
        context: _context,
        builder: (BuildContext context) {
          return WillPopScope(
            onWillPop: keluar,
            child: AlertDialog(
              shape: RoundedRectangleBorder(
                  borderRadius:
                      BorderRadius.all(Radius.circular(CustomStyle.boxRadius))),
              content: SingleChildScrollView(
                reverse: true,
                child: Column(
                  children: <Widget>[
                    Text(
                      message,
                      style: TextStyle(color: Colors.redAccent),
                    ),
                    jenisPeringatan == 'PermissionGPS'
                        ? Column(
                            children: [
                              SizedBox(
                                height: 24,
                              ),
                              Align(
                                alignment: Alignment.centerRight,
                                child: GestureDetector(
                                  onTap: () {
                                    BlocProvider.of<NavigatorBloc>(context)
                                        .add(NavigatePop(_context));
                                    AppSettings.openAppSettings();
                                  },
                                  child: Text(
                                    "Request Permission",
                                    style: TextStyle(
                                        color: CustomStyle.color1,
                                        fontWeight: FontWeight.w600,
                                        fontSize:
                                            CustomStyle.fontSizeSmall + 1),
                                  ),
                                ),
                              )
                            ],
                          )
                        : Container(),
                  ],
                ),
              ),
            ),
          );
        });
  }

  Future<bool> keluar() async {
    BlocProvider.of<NavigatorBloc>(context).add(NavigatePop(context));
    BlocProvider.of<NavigatorBloc>(context).add(NavigatePop(context));
    return false;
  }

  routeCameraX(Position? position, String kamera,MenuSos? redaksional) {
    _startCameraXActivity(position, kamera, true,redaksional);
  }

  Future<void> _startCameraXActivity(
      Position? position, String kamera, bool kameraBelakang,MenuSos? redaksional) async {
    setState(() {
      this.position = position;
      this.kamera2 = kamera;
      // registrasi = register;
    });
    try {
      // eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
      eventChannel.receiveBroadcastStream().listen((event){
        setState(() {
      _reportStatus = event.toString();
      CameraXRespon cameraXRespon = cameraXResponFromJson(_reportStatus);
      foto = cameraXRespon.foto;
      matrix = cameraXRespon.matrix;

      cameraModel =
          CameraModel(base64Encode(File(foto!).readAsBytesSync()), foto!);
      openDialog(position, context,redaksional, rotate: false);
    });
      }, onError: _onError);
      await methodChannel.invokeMethod('startCameraXActivity', {
        "kameraBelakang": kameraBelakang,
      });
    } on PlatformException catch (e) {
      debugPrint("Failed to Invoke: '${e.message}'.");
    }
  }

  // void _onEvent(Object? event) {
  //   setState(() {
  //     _reportStatus = event.toString();
  //     CameraXRespon cameraXRespon = cameraXResponFromJson(_reportStatus);
  //     foto = cameraXRespon.foto;
  //     matrix = cameraXRespon.matrix;

  //     cameraModel =
  //         CameraModel(base64Encode(File(foto!).readAsBytesSync()), foto!);
  //     openDialog(position, context, rotate: false);
  //   });
  //   print("Foto12: $foto");
  //   print("Matrix12: $matrix");
  //   print("INIREPORT ${_reportStatus.toString()}");
  //   debugPrint(_reportStatus);
  // }

  void _onError(Object error) {
    setState(() {
      _reportStatus = 'Camera status: ${error.toString()}';

      print("INIREPORT : ${error.toString()}");
    });
  }
}
