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

import 'package:camera/camera.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geolocator/geolocator.dart' as geo_location;
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:location/location.dart' as Location;
import 'package:provider/provider.dart';

import '../Utils/BackgroundLocationService.dart';
import '../Utils/SharedpreferencesService.dart';
import '../Utils/background_service.dart';
import '../Utils/commonServices.dart';
import '../services/api_calling.dart';

class CheckInOutProvider with ChangeNotifier {
  final ImagePicker _picker = ImagePicker();
  TextEditingController locationController = TextEditingController();
  GoogleMapController? mapController;
  LatLng startLocation = const LatLng(17.439112226708446, 78.43292499146135);
  LatLng? currentLocationLatLng;
  String latlongs = "";
  Set<Marker> markers = {};
  Location.LocationData? currentLocation;
  bool isLocationEnabled = false;
  bool hasLocationPermission = false;
  Timer? _timer;
  File? _image;
  int _imagePicked = 0;
  bool isLoading = true;
  String? validateLocation;
  String? empId;
  String? sessionId;
  late List<CameraDescription> _cameras;
  late CameraController cam_controller;
  File? get image => _image;
  int get imagePicked => _imagePicked;

  set imagePicked(int value) {
    _imagePicked = value;
    notifyListeners();
  }

  set image(value) {
    _image = value;
    notifyListeners();
  }

  Future<void> getCurrentLocation() async {
    try {
      Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: geo_location.LocationAccuracy.high,
      );
      currentLocationLatLng = LatLng(position.latitude, position.longitude);
      notifyListeners();
    } catch (e) {
      print("Error getting current location: $e");
    }
  }

  Future<void> getLocationPermission(BuildContext context) async {
    isLocationEnabled = await Geolocator.isLocationServiceEnabled();
    LocationPermission permission = await Geolocator.checkPermission();
    hasLocationPermission =
        permission == LocationPermission.always ||
        permission == LocationPermission.whileInUse;

    final Location.Location location = Location.Location();
    bool serviceEnabled = await location.serviceEnabled();
    if (!serviceEnabled) {
      serviceEnabled = await location.requestService();
      if (!serviceEnabled) {
        return;
      }
    }

    if (!isLocationEnabled || !hasLocationPermission) {
      permission = await Geolocator.requestPermission();
      if (permission != LocationPermission.always &&
          permission != LocationPermission.whileInUse) {
        showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text('Location Permission Required'),
              content: Text(
                'Please allow the app to access your location for core functionality.',
              ),
              actions: <Widget>[
                TextButton(
                  style: ButtonStyle(
                    backgroundColor: WidgetStateProperty.all(Colors.white),
                    overlayColor: WidgetStateProperty.all(Colors.white),
                  ),
                  onPressed: () async {
                    // await openAppSettings();
                    // Navigator.of(context).pop();
                    // Navigator.pushReplacement(
                    //   context,
                    //   MaterialPageRoute(builder: (context) => Attendance()),
                    // );
                  },
                  child: Text('OK'),
                ),
              ],
            );
          },
        );
        return;
      }
    }

    final Location.LocationData locData = await location.getLocation();
    currentLocation = locData;
    currentLocationLatLng = LatLng(locData.latitude!, locData.longitude!);
    isLoading = false;
    markers.clear();
    markers.add(
      Marker(
        markerId: MarkerId('current_location'),
        position: LatLng(locData.latitude!, locData.longitude!),
        infoWindow: InfoWindow(title: 'Current Location'),
        icon: BitmapDescriptor.defaultMarker,
      ),
    );
    latlongs = '${locData.latitude},${locData.longitude}';
    mapController?.animateCamera(
      CameraUpdate.newLatLng(LatLng(locData.latitude!, locData.longitude!)),
    );
    notifyListeners();
  }

  void onCameraMove(CameraPosition position, context) {
    _timer?.cancel();
    _timer = Timer(Duration(seconds: 1), () {
      getLocationPermission(context);
    });
  }

  // Future<void> getavailableCameras(context,attendanceStatus) async {
  //   try {
  //     _cameras = await availableCameras();
  //
  //     final frontCamera = _cameras.firstWhere(
  //           (camera) => camera.lensDirection == CameraLensDirection.front,
  //     );
  //
  //     cam_controller = CameraController(frontCamera, ResolutionPreset.max);
  //
  //     await cam_controller.initialize();
  //     if (!cam_controller.value.isInitialized) return;
  //     final image = await cam_controller.takePicture();
  //     _image = File(image.path);
  //     imagePicked = 1;
  //     var file = await FlutterImageCompress.compressWithFile(
  //       _image!.path,
  //     );
  //     if (file != null) {
  //       if (attendanceStatus == 0) {
  //         checkIn(context);
  //       } else if (attendanceStatus == 1) {
  //         checkOut(context);
  //       }
  //     }
  //   } catch (e) {
  //     toast(context, "Failed to initialize camera");
  //
  //   }
  // }
  Future<void> imgFromCamera(BuildContext context, attendanceStatus) async {
    if (locationController.text.isEmpty) {
      validateLocation = "Please Enter location";
      notifyListeners();
      return;
    }
    validateLocation = "";
    try {
      final XFile? galleryImage = await _picker.pickImage(
        source: ImageSource.camera,
        imageQuality: 50,
        preferredCameraDevice: CameraDevice.front,
      );
      if (galleryImage != null) {
        _image = File(galleryImage.path);
        _imagePicked = 1;
        var file = await FlutterImageCompress.compressWithFile(
          galleryImage.path,
        );
        if (file != null) {
          if (attendanceStatus == 0) {
            checkIn(context);
          } else if (attendanceStatus == 1) {
            checkOut(context);
          }
        }
      }
      notifyListeners();
    } catch (e) {
      debugPrint("Error capturing image: ${e.toString()}");
    }
  }

  Future<void> checkIn(BuildContext context) async {
    empId = await SharedpreferencesService().getString("UserId");
    sessionId = await SharedpreferencesService().getString("Session_id");
    if (kDebugMode) {
      // print(empId);
      // print(sessionId);
      // print(locationController.text);
      // print(latlongs);
      // print(_image);
    }
    try {
      isLoading = true;
      notifyListeners();
      final data = await ApiCalling.CheckInApi(
        empId,
        sessionId,
        locationController.text,
        latlongs,
        _image,
      );
      if (data != null) {
        if (data.error == 0) {
          toast(context, "CheckedIn Successfully");
          await BackgroundLocationService.startLocationService(context);
          locationController.clear();
          dispose();
          Navigator.pop(context, true);
        } else {
          toast(context, "Check-In UnSuccessful");
          print(data.error.toString());
        }
      } else {
        toast(context, "Something went wrong, Please try again.");
      }
    } catch (e) {
      print("Error during check-in: $e");
      toast(context, "Error during check-in.");
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  Future<void> checkOut(BuildContext context) async {
    empId = await SharedpreferencesService().getString("UserId");
    sessionId = await SharedpreferencesService().getString("Session_id");

    try {
      isLoading = true;
      notifyListeners();
      final data = await ApiCalling.CheckOutApi(
        empId,
        sessionId,
        locationController.text,
        latlongs,
        _image,
      );
      if (data != null) {
        if (data.error == 0) {
          toast(context, "Check-Out Successful");
          await BackgroundLocationService.stopLocationService();
          locationController.clear();
          dispose();
          Navigator.pop(context, true);
        } else {
          toast(context, "Check-Out UnSuccessful");
          print(data.error.toString());
        }
      } else {
        toast(context, "Something went wrong, Please try again.");
      }
    } catch (e) {
      print("Error during check-out: $e");
      toast(context, "Error during check-out.");
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }

  @override
  void dispose() {
    validateLocation = null;
    // locationController.dispose();
    locationController.clear();

    _timer?.cancel();
    notifyListeners();
  }
}
