import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:grocery_app/src/core/network_services/service_locator.dart';
import 'package:grocery_app/src/core/routes/routes.dart';
import 'package:grocery_app/src/data/address.dart';
import 'package:grocery_app/src/data/all_cart_items.dart';
import 'package:grocery_app/src/data/coupon_model.dart';
import 'package:grocery_app/src/data/coupon_response.dart';
import 'package:grocery_app/src/logic/repo/product_repo.dart';
import 'package:grocery_app/src/ui/payment/payment_webView.dart';
import 'package:grocery_app/utils/extensions/extensions.dart';
import 'package:http/http.dart' as http;

class AddtocartProvider extends ChangeNotifier {
  String _pinCode = "Fetching...";
  bool _isLoading = false;
  bool _isDeliverable = false;

  String get pinCode => _pinCode;
  bool get isLoading => _isLoading;

  TextEditingController checkPinCode = TextEditingController();

  Future<void> getCurrentLocation(BuildContext context) async {
    _isLoading = true;
    notifyListeners();

    try {
      bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
      if (!serviceEnabled) {
        _isLoading = false;
        notifyListeners();

        return;
      }

      Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high,
      );

      print("Location fetched: ${position.latitude}, ${position.longitude}");

      List<Placemark> placemarks = await placemarkFromCoordinates(
        position.latitude,
        position.longitude,
      );

      if (placemarks.isNotEmpty) {
        _pinCode = placemarks.first.postalCode ?? "Unknown";
        checkPinCode.text = _pinCode;
        print("Pincode found: $_pinCode");

        // Now check if this pin code is deliverable
        await checkPin(context, _pinCode);
      } else {
        _pinCode = "";
        print("Error: No placemarks found.");
      }
    } catch (e) {
      _pinCode = "";
      print("Error: ${e.toString()}");
    }
    _pinCode = "";
    _isLoading = false;
    notifyListeners();
  }

  bool ischeckpin = false;
  Future<void> checkPin(BuildContext context, pin) async {
    ischeckpin = true;
    _pinCode = pin;
    notifyListeners();
    var data = {};
    try {
      var result = await _homeRepo.checkPin(data, pin);

      return result.fold(
        (error) {
          ischeckpin = false;
          _isDeliverable = false;
          isLoaddcartItem = false;
          notifyListeners();
        },
        (response) {
          if (response.isDeliverable!) {
            _isDeliverable = true;
          }
          ischeckpin = false;
          isLoaddcartItem = false;
          notifyListeners();
        },
      );
    } catch (e) {
      ischeckpin = false;
      _isDeliverable = false;
      isLoaddcartItem = false;
      notifyListeners();
    }
  }

  bool get isDeliverable => _isDeliverable;
  int deliveryCharge = 0;
  int get getdeliverycharge => deliveryCharge;

  Future<void> checkAddress(BuildContext context, addressId) async {
    ischeckpin = true;

    notifyListeners();
    var data = {};
    try {
      var result = await _homeRepo.checkAddress(data, addressId);

      return result.fold(
        (error) {
          _isDeliverable = false;

          notifyListeners();
        },
        (response) {
          print(
              "sjhjkdkfhgjdfkjgdfgjdfjjkhsdfghhfjkd    ${response.isDeliverable}");

          if (response.isDeliverable!) {
            _isDeliverable = true;
            deliveryCharge = response.maxDeliveryCharges!;
          }
          ischeckpin = false;

          notifyListeners();
        },
      );
    } catch (e) {
      _isDeliverable = false;

      notifyListeners();
    }
  }

// checkAddress
  Map<String, bool> isRemoveItem = {};

  Future<void> deleteItem(BuildContext context, id) async {
    isRemoveItem[id] = true;
    notifyListeners();
    var data = {};
    try {
      var result = await _homeRepo.deleteItem(data, id);
      return result.fold(
        (error) {
          isRemoveItem[id] = false;
          notifyListeners();
        },
        (response) {
          getItemCards(context);
          isRemoveItem[id] = false;
          notifyListeners();
        },
      );
    } catch (e) {
      isRemoveItem[id] = false;

      notifyListeners();
    }
  }

  double _totalPrice = 0.0;
  double _grandPrice = 0.0;
  double _discount = 0.0;

  double get totalPrice => _totalPrice;

  double get grandPrice => _grandPrice;

  double get discount => _discount;

  final _homeRepo = getIt<ProductRepo>();

  AllCartItems allitem = AllCartItems();

  bool isLoaddcartItem = true;
  Future<void> getItemCards(BuildContext context) async {
    isLoaddcartItem = true;
    notifyListeners();
    var data = {};
    try {
      var result = await _homeRepo.getItemCards(data);

      return result.fold(
        (error) {
          isLoaddcartItem = false;
          notifyListeners();
        },
        (response) {
          allitem = response!;
          _discount = 0.0;
          _totalPrice = double.parse(response.subtotal.toString());
          _grandPrice = double.parse(response.subtotal.toString());

          isLoaddcartItem = false;
          notifyListeners();
        },
      );
    } catch (e) {
      print("sfddsfdfff");
      isLoaddcartItem = false;
      notifyListeners();
    }
  }
  //////////////////////////////////// coupon ////////////////////////////

  bool iscouponLoading = true;

  CouponDataModel couponDataModel = CouponDataModel();
  Future<void> offerCoupon(BuildContext context) async {
    iscouponLoading = true;
    notifyListeners();
    var data = {};
    try {
      var result = await _homeRepo.offerCoupon(data);

      return result.fold(
        (error) {
          iscouponLoading = false;
          notifyListeners();
        },
        (response) {
          print("kdjgkjfghjkfghjkl   ${response.data}");
          couponDataModel = response!;
          iscouponLoading = false;
          notifyListeners();
        },
      );
    } catch (e) {
      iscouponLoading = false;
      notifyListeners();
    }
  }

  bool isCouponApply = false;
  CouponResponse couponResponse = CouponResponse();

  String _couponId = '';
  String get couponId => _couponId;

  Future<bool> applyCoupon(
      BuildContext context, String cartId, String couponscode, id) async {
    context.showLoader(show: true);
    isCouponApply = true;

    notifyListeners();

    var data = {"couponCode": couponscode, "cartId": cartId};
    try {
      var result = await _homeRepo.applyCoupon(data);

      return result.fold(
        (error) {
          context.showLoader(show: false);
          isCouponApply = false;
          Fluttertoast.showToast(
            msg: "${error.message}",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.BOTTOM,
            backgroundColor: Colors.red,
            textColor: Colors.white,
            fontSize: 14.0,
          );
          notifyListeners();
          return false;
        },
        (response) {
          if (response != null) {
            couponResponse = response;
            _couponId = id;
            _grandPrice = double.parse(response.finalPrice.toString());
            _discount = double.parse(response.discountAmount.toString());
            context.showLoader(show: false);
            isCouponApply = false;
            notifyListeners();
            return true;
          } else {
            context.showLoader(show: false);
            isCouponApply = false;
            notifyListeners();
            return false;
          }
        },
      );
    } catch (e) {
      context.showLoader(show: false);
      Fluttertoast.showToast(
        msg: "Coupon Code invalid!",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 14.0,
      );
      isCouponApply = false;
      notifyListeners();
      return false; // Return false on exception
    }
  }

///////////////////////////////////orderPaymnet///////////////////////////

  bool ispaymentLoader = false;
  Future<void> orderPaymnet(
    BuildContext context,
    double originalAmount,
    String cartId,
    String addressId,
    String couponId,
  ) async {
    ispaymentLoader = true;
    notifyListeners();
    var data;

    if (couponId.isEmpty) {
      data = {
        "amount": originalAmount,
        "addressId": addressId,
        "cartId": cartId,
      };
    } else {
      data = {
        "amount": originalAmount,
        "addressId": addressId,
        "cartId": cartId,
        "couponId": couponId
      };
    }

    try {
      var result = await _homeRepo.paymentOrder(data);
      return result.fold(
        (error) {
          ispaymentLoader = false;
          notifyListeners();
        },
        (response) {
          if (response.data!.instrumentResponse!.redirectInfo != null &&
              response.data!.instrumentResponse!.redirectInfo != '') {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => PaymentWebView(
                    paymentUrl:
                        response.data!.instrumentResponse!.redirectInfo!.url),
              ),
            );
          }
          ispaymentLoader = false;
          notifyListeners();
        },
      );
    } catch (e) {
      ispaymentLoader = false;

      Fluttertoast.showToast(
        msg: "Internal server error!",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 14.0,
      );
      notifyListeners();
    }
  }

  ////////////////////////////COD ////////////

  Future<void> paymentCODOrder(
    BuildContext context,
    double subtotal,
    int deliverCharge,
    String couponId,
    String addressId,
  ) async {
    ispaymentLoader = true;
    notifyListeners();
    var data;
    if (couponId.isNotEmpty) {
      data = {
        "addressId": addressId,
        "paymentMethod": "COD",
        "paymentStatus": "PENDING",
        "orderStatus": "PENDING",
        "subtotal": subtotal,
        "deliveryCharge": deliverCharge,
        "transactionId": "phonepe_transaction_123",
        "couponId": couponId
      };
    } else {
      data = {
        "addressId": addressId,
        "paymentMethod": "COD",
        "paymentStatus": "PENDING",
        "orderStatus": "PENDING",
        "subtotal": subtotal,
        "deliveryCharge": deliverCharge,
      };
    }

    print("kjfhxgkljfhg  ${data}");

    try {
      var result = await _homeRepo.paymentCODOrder(data);

      return result.fold(
        (error) {
          Fluttertoast.showToast(
            msg: "${error.message}",
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.BOTTOM,
            backgroundColor: Colors.green,
            textColor: Colors.white,
            fontSize: 14.0,
          );
          ispaymentLoader = false;
          notifyListeners();
        },
        (response) {
          context.clearAndPush(routePath: MyRoutes.SUCCESSPAYMENT);

          ispaymentLoader = false;
          notifyListeners();
        },
      );
    } catch (e) {
      ispaymentLoader = false;

      Fluttertoast.showToast(
        msg: "${e}",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
        backgroundColor: Colors.green,
        textColor: Colors.white,
        fontSize: 14.0,
      );
      notifyListeners();
    }
  }

/////////////////////////////////  address/////////////////////////
  List<Datum> addresslist = [];

  Future<void> getAddress(BuildContext context) async {
    var data = {};
    try {
      var result = await _homeRepo.getAddress(data);

      return result.fold(
        (error) {
          print("dsjfgkjhkdfgdkjfhg");

          notifyListeners();
        },
        (response) {
          addresslist = response.data!;
          if (response.data!.isNotEmpty) {
            //checkAddress(context, addresslist.first.id ?? "");
            // _selectedAddress = addresslist.first.id ?? "";
            _selecteUserName = addresslist.first.name ?? "";
            _selecteUserPhone = addresslist.first.phoneNumber ?? "";
            _selecteEmail = addresslist.first.user!.email ?? "";
          } else {
            _selectedAddress = "";
          }

          notifyListeners();
        },
      );
    } catch (e) {
      print("sfddsfdfff");

      notifyListeners();
    }
  }

  String _selecteUserName = "";
  String _selecteUserPhone = "";
  String _selecteEmail = "";
  String _selectedAddress = "";
  String get selectedAddress => _selectedAddress;
  String get selecteUserName => _selecteUserName;
  String get selecteUserPhone => _selecteUserPhone;
  String get selecteEmail => _selecteEmail;
  selectedAddressId() {
    _selectedAddress = "";
    notifyListeners();
  }

  void bydefaultSetAddress(phoneNumber, name, email) {
    _selecteUserName = name;
    _selecteUserPhone = phoneNumber;
    _selecteEmail = email;
    notifyListeners();
  }

  void selectAddress(String address, phoneNumber, name, email) {
    print("lksdjfhgkfdghhkkfdghkjfjdgkh");
    _selectedAddress = address;
    _selecteUserName = name;
    _selecteUserPhone = phoneNumber;
    _selecteEmail = email;
    notifyListeners();
  }

  Set<String> cartItems = {};
  Map<String, bool> isLoadings = {};

  bool isLoadingCart = false;
  bool iscardAdded = false;

  Future<void> addToCart(
      BuildContext context, String productId, int quantity) async {
    context.showLoader(show: true);

    isLoadingCart = true;
    isLoadings[productId] = true;
    notifyListeners();

    var data = {"productId": productId, "quantity": quantity};

    try {
      var result = await _homeRepo.addToCart(data);
      context.showLoader(
        show: false,
      );

      result.fold(
        (error) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(error.message),
              backgroundColor: Colors.red,
            ),
          );
        },
        (response) async {
          print("kldfjghlkjfgkljh");
          await getItemCards(context);
          cartItems.add(productId);

          iscardAdded = true;
          notifyListeners();
        },
      );
    } catch (e) {
      Fluttertoast.showToast(
        msg: "Insufficient stock!",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        backgroundColor: Colors.red,
        textColor: Colors.white,
        fontSize: 14.0,
      );

      context.showLoader(show: false);
      await getItemCards(context);

      // isLoadingCart = false;
      // iscardAdded = true;
      // isLoadings[productId] = false;
      notifyListeners();
    } finally {
      isLoadingCart = false;
      isLoadings[productId] = false;
      notifyListeners(); // Ensure UI updates after operation
    }
  }

  Future<void> decreaseCartQuantity(
      BuildContext context, String itemId, int quantity) async {
    context.showLoader(show: true);

    isLoadingCart = true;

    notifyListeners();

    // var data = {"productId": productId, "quantity": quantity};

    final Map<String, dynamic> cartData = {
      "items": [
        {"itemId": itemId, "quantity": quantity}
      ]
    };

    try {
      var result = await _homeRepo.decreaseQuantity(cartData);
      context.showLoader(
        show: false,
      );

      result.fold(
        (error) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(error.message),
              backgroundColor: Colors.red,
            ),
          );
        },
        (response) async {
          await getItemCards(context);

          // Fluttertoast.showToast(
          //   msg: "Added to cart successfully!",
          //   toastLength: Toast.LENGTH_SHORT,
          //   gravity: ToastGravity.BOTTOM,
          //   backgroundColor: Colors.green,
          //   textColor: Colors.white,
          //   fontSize: 14.0,
          // );
          iscardAdded = true;
          notifyListeners(); // Update UI after adding to cart
        },
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text("Something went wrong"),
          backgroundColor: Colors.red,
        ),
      );
    } finally {
      isLoadingCart = false;

      notifyListeners(); // Ensure UI updates after operation
    }
  }

  String _selectedPaymentMethod = "Online"; // Default selection

  String get selectedPaymentMethod => _selectedPaymentMethod;

  void selectPaymentMethod(String method) {
    _selectedPaymentMethod = method;
    notifyListeners();
  }
}
