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

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fpdart/fpdart.dart';
import 'package:grocery_app/src/core/routes/routes.dart';
import 'package:grocery_app/src/core/utils/custom_dio_exception.dart';
import 'package:grocery_app/src/core/utils/response_type_def.dart';
import 'package:grocery_app/src/data/ProductCategoryModel.dart';
import 'package:grocery_app/src/data/address.dart';
import 'package:grocery_app/src/data/allProduct_model.dart';
import 'package:grocery_app/src/data/all_cart_items.dart';
import 'package:grocery_app/src/data/banners.dart';
import 'package:grocery_app/src/data/best_dealProduct.dart';
import 'package:grocery_app/src/data/check_pin_response.dart';
import 'package:grocery_app/src/data/check_product.dart';
import 'package:grocery_app/src/data/cod_order_response.dart';
import 'package:grocery_app/src/data/coupon_model.dart';
import 'package:grocery_app/src/data/coupon_response.dart';
import 'package:grocery_app/src/data/login_response.dart';
import 'package:grocery_app/src/data/order_paymnet.dart';
import 'package:grocery_app/src/data/product_category.dart';
import 'package:grocery_app/src/data/product_details.dart';
import 'package:grocery_app/src/data/upload_image.dart';
import 'package:grocery_app/src/data/user_profile.dart';
import 'package:grocery_app/src/data/wish_list_model.dart';
import 'package:grocery_app/src/logic/services/home_locator.dart';
import 'package:grocery_app/src/ui/productdetails/product_details.dart';
import 'package:grocery_app/utils/constants/shared_pref_utils.dart';
import 'package:grocery_app/utils/extensions/extensions.dart';

class ProductRepo {
  final ProductService _productService;

  ProductRepo(this._productService);

  FutureResult<AllProductModel> getAllProduct(
      data, BuildContext context, id) async {
    try {
      var response = await _productService.getAllProduct(data, id);

      AllProductModel loginResponse =
          allProductModelFromJson(response.toString());

      final String model = response.toString();

      return right(loginResponse);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<ProductDetailsData> getProductDetails(
      data, BuildContext context, id) async {
    try {
      var response = await _productService.getProductDetails(data, id);

      ProductDetailsData loginResponse =
          productDetailsDataFromJson(response.toString());

      final String model = response.toString();

      return right(loginResponse);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<BestDealProduct> getBestDealProduct(
      data, BuildContext context) async {
    try {
      var response = await _productService.getBestDealProduct(data);

      BestDealProduct loginResponse =
          bestDealProductFromJson(response.toString());

      final String model = response.toString();

      return right(loginResponse);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<ProductCategory> getAllcategory(
      data, BuildContext context) async {
    try {
      var response = await _productService.getAllcategory(data);

      ProductCategory productCategory =
          productCategoryFromJson(response.toString());

      // final String model = response.toString();

      return right(productCategory);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<List<DatumCategory>> getSubcategory(
      data, BuildContext context) async {
    try {
      var response = await _productService.getSubcategory(data);

      print("Response Type: ${response.runtimeType}");
      print("Raw Response: ${response.data}");

      List<DatumCategory> categoryList;

      if (response.data is List) {
        categoryList = (response.data as List)
            .map((item) => DatumCategory.fromJson(item))
            .toList();
        ;
      } else {
        categoryList = (jsonDecode(response) as List)
            .map((item) => DatumCategory.fromJson(item))
            .toList();
      }

      print("Raw Response: $response");

      // final String model = response.toString();

      return right(categoryList);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<List<ProductCategoryModel>> getCategoryByLevel(data) async {
    try {
      var response = await _productService.getCategoryByLevel(data);

      final List<ProductCategoryModel> productModels = (response.data as List)
          .map((item) => ProductCategoryModel.fromJson(item))
          .toList();
      if (response != null && response.data != null) {
        // Parse the response data into a list of ProductCategoryModel
        final List<ProductCategoryModel> productModels = (response.data as List)
            .map((item) => ProductCategoryModel.fromJson(item))
            .toList();

        // Print or handle the fetched data
        if (productModels.isNotEmpty) {
          print(
              "Data successfully fetched and parsed: ${productModels.length} categories.");
        }
      }
      return right(productModels);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<OrderPaymnet> paymentOrder(data) async {
    try {
      var response = await _productService.paymentOrder(data);
      print("kjdfglkjfdgjklfgkldj${data}  ${response} ");

      OrderPaymnet productCategory = orderPaymnetFromJson(response.toString());

      print("lkjdflkjfhgdkhfgkd  ");
      // final String model = response.toString();

      return right(productCategory);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<CodOrderResponse> paymentCODOrder(data) async {
    try {
      var response = await _productService.paymentCODOrder(data);
      CodOrderResponse productCategory =
          codOrderResponseFromJson(response.toString());

      return right(productCategory);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<List<Product>> similarProduct(
      data, BuildContext context, id) async {
    try {
      var response = await _productService.similarProduct(data, id);

      List<Product> products = (response as List)
          .map((item) => Product.fromJson(item as Map<String, dynamic>))
          .toList();

      print("sdkjfkjdkfjgjfdjg");

      return right(products);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<AllCartItems> getItemCards(data) async {
    try {
      var response = await _productService.getItemCards(data);

      AllCartItems allCartItems = allCartItemsFromJson(response.toString());
      return right(allCartItems);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<CouponDataModel> offerCoupon(data) async {
    try {
      var response = await _productService.offerCoupon(data);

      CouponDataModel couponmodel = couponDataFromJson(response.toString());
      return right(couponmodel);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<CouponResponse> applyCoupon(data) async {
    try {
      var response = await _productService.applyCoupon(data);

      CouponResponse couponresponse =
          couponResponseFromJson(response.toString());
      return right(couponresponse);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<AddressResponse> getAddress(data) async {
    try {
      var response = await _productService.getAddress(data);

      AddressResponse allCartItems =
          addressResponseFromJson(response.toString());

      return right(allCartItems);
    } on DioException catch (e) {
      print("sdkjfkjdkfjgjfdjg");
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<UserProfile> getProfile(data) async {
    try {
      var response = await _productService.getProfile(data);

      print("kdjfgkljfdkjlghflkgjh  ${response}");
      UserProfile userProfile = userProfileFromJson(response.toString());
      print("kdjfgkljfdkjlghflkgjhrerrrerr  ${userProfile.createdAt}");
      return right(userProfile);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> updateProfile(data) async {
    try {
      var response = await _productService.updateProfile(data);

      final String model = response.toString();
      return right(model);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<UploadImage> uploadImage(File imageFile) async {
    try {
      final response = await _productService.uploadImage(imageFile);
      UploadImage upload = uploadImageFromJson(response.toString());
      return right(upload);
    } on DioException catch (e) {
      final error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<CheckPinResponse> checkPin(data, pin) async {
    try {
      var response = await _productService.checkPin(data, pin);
      CheckPinResponse allCartItems =
          checkPinResponseFromJson(response.toString());

      return right(allCartItems);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<CheckProduct> checkAddress(data, id) async {
    try {
      var response = await _productService.checkAddress(data, id);

      print("kjlkjcjgklkjdhgfgkjfkdjghkjf  $response");

      CheckProduct productCategory = checkProductFromJson(response.toString());

      print("kjxfgklhdfkgjkjdfg  $productCategory");

      return right(productCategory);
    } on DioException catch (e) {
      print("lkjxhdfgkfglkhkjfgh  $e");
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> deleteItem(data, id) async {
    try {
      var response = await _productService.deleteItem(data, id);
      final String model = response.toString();

      return right(model);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> addAddress(data) async {
    try {
      var response = await _productService.addAddress(data);

      final String model = response.toString();

      return right(model);
    } on DioException catch (e) {
      print("djhgfjdfhjg  ${e}");
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> addToWish(data) async {
    try {
      var response = await _productService.addToWish(data);

      final String model = response.toString();

      return right(model);
    } on DioException catch (e) {
      print("djhgfjdfhjg  ${e}");
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> addToCart(data) async {
    try {
      var response = await _productService.addToCart(data);

      final String model = response.toString();

      return right(model);
    } on DioException catch (e) {
      print("djhgfjdfhjg  ${e}");
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> decreaseQuantity(data) async {
    try {
      var response = await _productService.decreaseQuantity(data);

      final String model = response.toString();

      return right(model);
    } on DioException catch (e) {
      print("djhgfjdfhjg  ${e}");
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<WishListModel> gettAllWishList(data) async {
    try {
      var response = await _productService.gettAllWishList(data);
      WishListModel wishListModel = wishListModelFromJson(response.toString());

      // final String model = response.toString();

      return right(wishListModel);
    } on DioException catch (e) {
      print("djhgfjdfhjg  ${e}");
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<BannerModel> getBanners(data, BuildContext context) async {
    try {
      var response = await _productService.getBanners(data);

      BannerModel bannerresponse = bannerFromJson(response.toString());

      print("skjdgkjdsf  ${bannerresponse}");

      final String model = response.toString();

      return right(bannerresponse);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> customerLogOut(data) async {
    try {
      var response = await _productService.customerLogOut(data);

      final String model = response.toString();

      return right(model);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  FutureResult<String> refreshToken(data, BuildContext context) async {
    try {
      var response = await _productService.refresh_token(data);
      LoginResponse loginResponse = loginResponseFromJson(response.toString());

      if (loginResponse.accessToken != null) {
        await SharedPrefUtils.setToken(
            authToken: loginResponse.accessToken ?? "");
        await SharedPrefUtils.setRefreshToken(
            refresh_token: loginResponse.refreshToken ?? "");
      }

      final String model = response.toString();

      return right(model);
    } on DioException catch (e) {
      var error = CustomDioExceptions.handleError(e);
      return left(error);
    }
  }

  // FutureResult<VendorModel> getMe(data) async {
  //   try {
  //     var response = await _homeService.getMe(data);

  //     final VendorModel vendorModel = vendorModelFromJson(response.toString());

  //     if (vendorModel != null)
  //     {
  //       SharedPrefUtils.USER_NAME =
  //           vendorModel.firstName + " " + vendorModel.lastName;
  //           SharedPrefUtils.PHONE = vendorModel.phone;

  //       print("dkfjhdkfhkfk  ${SharedPrefUtils.USER_NAME}");
  //       await SharedPrefUtils.setStoreId(storeId: vendorModel.storeId ?? "");

  //     }

  //     final String model = response.toString();

  //     return right(vendorModel);
  //   } on DioException catch (e) {
  //     var error = CustomDioExceptions.handleError(e);
  //     return left(error);
  //   }
  // }
}
