import 'dart:io';

import 'package:bookmywages/model/Banner_model.dart';
import 'package:bookmywages/model/Categories_model.dart';
import 'package:bookmywages/model/booking_modify_model.dart';
import 'package:bookmywages/model/cancel_booking.dart';
import 'package:bookmywages/model/detail_page_model.dart';
import 'package:bookmywages/model/enquriy_list_model.dart';
import 'package:bookmywages/model/enquriy_model.dart';
import 'package:bookmywages/model/expired_plan_model.dart';
import 'package:bookmywages/model/get_review_model.dart';
import 'package:bookmywages/model/most_popular_model.dart';
import 'package:bookmywages/model/notification_model.dart';
import 'package:bookmywages/model/otp_model.dart';
import 'package:bookmywages/model/package_model.dart';
import 'package:bookmywages/model/payment_details_model.dart';
import 'package:bookmywages/model/plan_sucess_model.dart';
import 'package:bookmywages/model/profile_get_model.dart';
import 'package:bookmywages/model/service_model.dart';
import 'package:bookmywages/model/subcategory_model.dart';
import 'package:bookmywages/model/user_booking_details.dart';
import 'package:bookmywages/model/vendor_model/terms_and_conditions_model.dart';
import 'package:bookmywages/model/vendor_model/vendor_booking_model.dart'
    show VendorBookingModel;
import 'package:bookmywages/model/vendor_model/vendor_booking_status.dart';
import 'package:bookmywages/model/vendor_model/vendor_catgories_model.dart';
import 'package:bookmywages/model/vendor_model/vendor_profile_model.dart';
import 'package:bookmywages/model/vendor_model/vendor_service_model.dart';
import 'package:bookmywages/model/vendor_model/vendor_serviceupload_model.dart';
import 'package:bookmywages/model/vendor_model/vendorregister_model.dart';
import 'package:bookmywages/view/auth/auth_repository.dart';
import 'package:bookmywages/view/user_main_screens/notification_page.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/login_model.dart';

import '../viewmodel/consts_api.dart';

final loginRepositoryProvider = Provider((ref) => AuthRepository());

final loginFutureProvider = FutureProvider.family
    .autoDispose<Map<String, dynamic>, LoginModel>((ref, loginModel) async {
      final repo = ref.read(loginRepositoryProvider);
      return repo.loginUser(ConstsApi.login, loginModel);
    });

final signupFutureProvider = FutureProvider.family
    .autoDispose<Map<String, dynamic>, Map<String, dynamic>>((
      ref,
      signupData,
    ) async {
      final repo = ref.read(loginRepositoryProvider);
      return repo.registerUser(ConstsApi.register, signupData);
    });
// Add this to your providers file
final otpVerificationProvider = FutureProvider.family
    .autoDispose<Map<String, dynamic>, OtpModel>((ref, otpModel) async {
      final repo = ref.read(loginRepositoryProvider);
      return repo.verifyOtp(ConstsApi.otp, otpModel);
    });
final bannerRepositoryProvider = Provider((ref) => BannerRepository());

final bannerListProvider = FutureProvider.autoDispose<List<BannerModel>>((
  ref,
) async {
  final repo = ref.read(bannerRepositoryProvider);
  return repo.fetchBanners(ConstsApi.banner);
});
final categoryRepositoryProvider = Provider((ref) => CategoryRepository());

final categoryListProvider = FutureProvider.autoDispose<List<CategoriesModel>>((
  ref,
) async {
  final repo = ref.read(categoryRepositoryProvider);
  return repo.fetchCategories(ConstsApi.catgories);
});

final packageRepositoryProvider = Provider((ref) => packageRepository());

final pacakgeProvider = FutureProvider.autoDispose<List<PackageModel>>((
  ref,
) async {
  final repo = ref.read(packageRepositoryProvider);
  return repo.fetchpackage(ConstsApi.package);
});

final profilegetRepositoryProvider = Provider((ref) => ProfilegetRepository());

final profilegetuserProvider =
    FutureProvider.autoDispose<List<ProfileGetModel>>((ref) async {
      final repo = ref.read(profilegetRepositoryProvider);
      return repo.fetchprofileget(ConstsApi.profileget);
    });
final subcategoryRepositoryProvider = Provider(
  (ref) => SubcategoryRepository(),
);

final subcategoryProvider = FutureProvider.family
    .autoDispose<List<SubcategoryModel>, String>((ref, categoryId) async {
      final repo = ref.read(subcategoryRepositoryProvider);
      return repo.fetchSubcategories(ConstsApi.subcat, categoryId);
    });

final serviceRepositoryProvider = Provider((ref) => ServiceRepository());

final serviceProvider = FutureProvider.family
    .autoDispose<
      List<ServiceModel>,
      ({String categoryId, String? subcategoryId, String? selecttype})
    >((ref, params) async {
      final repo = ref.read(serviceRepositoryProvider);
      return repo.fetchService(
        ConstsApi.service,
        params.categoryId,
        params.subcategoryId,
        params.selecttype,
      );
    });
final profileupdateRepositoryProvider = Provider(
  (ref) => ProfileupdateRepository(),
);

final profileupdateuserProvider =
    FutureProvider.autoDispose<List<ProfileGetModel>>((ref) async {
      final repo = ref.read(profileupdateRepositoryProvider);
      return repo.fetchprofileupdate(ConstsApi.upadateprofile);
    });
final getreviewRepositoryProvider = Provider((ref) => GetReviewRepository());

final getreviewuserProvider =
    FutureProvider.family<List<GetReviewModel>, String>((ref, serviceId) async {
      final repo = ref.read(getreviewRepositoryProvider);
      return repo.fetchgetreview(ConstsApi.getreview, serviceId);
    });

final mostPopularRepositoryProvider = Provider(
  (ref) => MostPopularRepository(),
);

// Create a provider family that accepts a categoryId parameter
final mostPopularProvider =
    FutureProvider.family<List<MostPopularModel>, String>((
      ref,
      categoryId,
    ) async {
      final repo = ref.read(mostPopularRepositoryProvider);
      return repo.fetchMostPopular(ConstsApi.mostpopular, categoryId);
    });

final enquriyupdateRepositoryProvider = Provider((ref) => EnquriyRepository());

final enquriyProvider = FutureProvider.autoDispose<List<EnquiryModel>>((
  ref,
) async {
  final repo = ref.read(enquriyupdateRepositoryProvider);
  return repo.fetchenquriy(ConstsApi.enquery);
});

final enquriyRepositoryProvider = Provider((ref) => enquriylistRepository());

final enquriylistProvider = FutureProvider.autoDispose<List<EnquiryListModel>>((
  ref,
) async {
  final repo = ref.read(enquriyRepositoryProvider);
  return repo.fetchenquirylist(ConstsApi.enquirylist);
});

final enquriydeleteRepositoryProvider = Provider(
  (ref) => EnquriydeleteRepository(),
);

final enquriydeleteProvider = FutureProvider.autoDispose.family<bool, String>((
  ref,
  id,
) async {
  final repo = ref.read(enquriydeleteRepositoryProvider);
  return repo.enquriydelete(ConstsApi.enquirydelete, id);
});

final paymentlistRepositoryProvider = Provider(
  (ref) => PaymentdetailsRepository(),
);

final paymentdetailsProvider =
    FutureProvider.autoDispose<List<PaymentDetailsModel>>((ref) async {
      final repo = ref.read(paymentlistRepositoryProvider);
      return repo.fetchpayment(ConstsApi.paymentdetails);
    });

final paymentdeleteRepositoryProvider = Provider(
  (ref) => PaymentdeleteRepository(),
);

final paymentdeleteProvider = FutureProvider.autoDispose.family<bool, String>((
  ref,
  id,
) async {
  final repo = ref.read(paymentdeleteRepositoryProvider);
  return repo.paymentdelete(ConstsApi.paymentdelete, id);
});

final changepassRepositoryProvider = Provider(
  (ref) => ChangepasswordRepository(),
);

final changepasswordProvider = FutureProvider.autoDispose.family<bool, String>((
  ref,
  password,
) async {
  final repo = ref.read(changepassRepositoryProvider);
  return repo.changepassword(ConstsApi.changepassword, password);
});

final servicebookinguserhistorydetailsRepositoryProvider = Provider(
  (ref) => UserhistoryBookingdetailsRepository(),
);

final userbookinghistorydetailsProvider =
    FutureProvider.autoDispose<List<UserBookingDetails>>((ref) async {
      final repo = ref.read(servicebookinguserhistorydetailsRepositoryProvider);
      return repo.fetchhistorybooking(ConstsApi.historybooking);
    });

final cancelbookingRepositoryProvider = Provider(
  (ref) => CancelbookingRepository(),
);

final cancelbookingProvider = FutureProvider.autoDispose
    .family<bool, CancelBookingRequest>((ref, data) async {
      final repo = ref.read(cancelbookingRepositoryProvider);
      return repo.cancelbooking(
        url: ConstsApi.cancelbooking,
        id: data.id,
        serviceId: data.serviceId,
        type: data.type,
      );
    });
final bookingmodifyRepositoryProvider = Provider(
  (ref) => BookingmodifyRepository(),
);

final modifybookingProvider = FutureProvider.autoDispose
    .family<bool, BookingModifyModel>((ref, data) async {
      final repo = ref.read(bookingmodifyRepositoryProvider);
      return repo.bookingmodify(
        url: ConstsApi.bookingmodify,
        id: data.id,
        serviceId: data.serviceId,
        servicedate: data.servicedate,
        servicetime: data.servicetime,
      );
    });

final expiredPlanRepositoryProvider = Provider(
  (ref) => ExpiredPlanRepository(),
);

final expiredPlanProvider = FutureProvider.autoDispose<ExpiredPlanModel>((
  ref,
) async {
  final repo = ref.read(expiredPlanRepositoryProvider);
  return repo.fetchExpiredPlan(ConstsApi.expiredplan);
});

final planSuccessRepositoryProvider = Provider(
  (ref) => PlanSuccessRepository(),
);

// Provider for plan success functionality
final planSuccessProvider = FutureProvider.autoDispose
    .family<bool, PlanSuccessModel>((ref, data) async {
      final repo = ref.read(planSuccessRepositoryProvider);
      return repo.planSuccess(
        url: ConstsApi.plansucess,
        userId: data.userId,
        planId: data.planId,
        duration: data.duration,
        type: data.type,
      );
    });

final detailpageRepositoryProvider = Provider((ref) => DetailpageRepository());

final detailpageProvider = FutureProvider.family
    .autoDispose<List<DetailPageModel>, String>((ref, serviceid) async {
      final repo = ref.read(detailpageRepositoryProvider);
      return repo.fetchDetailpage(ConstsApi.detail, int.parse(serviceid));
    });

//--------------------vendor flow-----------------------------------------

final getvendorIdRepositoryProvider = Provider((ref) => GetvendorId());

final getvendorIdProvider = FutureProvider.autoDispose((ref) async {
  final repo = ref.read(getvendorIdRepositoryProvider);
  return repo.fetchGetid(ConstsApi.getvendorid);
});

final vendorRegisterRepositoryProvider = Provider((ref) => VendorRegister());

// Future provider to call the register API
final vendorRegisterFutureProvider = FutureProvider.family
    .autoDispose<Map<String, dynamic>, VendorRegisterModel>((
      ref,
      vendorModel,
    ) async {
      final repo = ref.read(vendorRegisterRepositoryProvider);
      return repo.vendorRegister(ConstsApi.vendorregister, vendorModel);
    });

final vendorserviceuploadRepositoryProvider = Provider(
  (ref) => Vendorserviceupload(),
);

final vendorserviceFutureProvider = FutureProvider.family
    .autoDispose<Map<String, dynamic>, (VendorServiceUploadModel, List<File>)>((
      ref,
      data,
    ) async {
      final repo = ref.read(vendorserviceuploadRepositoryProvider);
      return repo.vendorserviceupload(
        ConstsApi.vendorserivceupload,
        data.$1, // VendorServiceUploadModel
        data.$2, // List<File> images
      );
    });

final vendorbookingdetailsRepositoryProvider = Provider(
  (ref) => VendorbookingdetailsRepository(),
);

final vendorbookingdetailsProvider =
    FutureProvider.autoDispose<List<VendorBookingModel>>((ref) async {
      final repo = ref.read(vendorbookingdetailsRepositoryProvider);
      return repo.fetchvendorbooking(ConstsApi.vendormybooking);
    });

final changebookingstatusRepositoryProvider = Provider(
  (ref) => ChangebookingstatusRepository(),
);

final changebookingProvider = FutureProvider.autoDispose
    .family<bool, VendorBookingStatus>((ref, data) async {
      final repo = ref.read(changebookingstatusRepositoryProvider);
      return repo.changebooking(
        url: ConstsApi.vendorchangebookingstatus,
        id: data.id.toString(),
        status: data.status.toString(),
      );
    });

final vendorcatgoriesRepositoryProvider = Provider(
  (ref) => VendorcatgoriesRepository(),
);

final vendorcatgoriesProvider =
    FutureProvider.autoDispose<List<VendorCategoriesModel>>((ref) async {
      final repo = ref.read(vendorcatgoriesRepositoryProvider);
      return repo.fetchvendorcat(ConstsApi.vendorcat);
    });

final vendorserviceRepositoryProvider = Provider(
  (ref) => VendorserviceRepository(),
);

final vendorserviceProvider =
    FutureProvider.autoDispose<List<VendorServiceModel>>((ref) async {
      final repo = ref.read(vendorserviceRepositoryProvider);
      return repo.fetchvendorservice(ConstsApi.vendormyservice);
    });

final vendorserviceupdateRepositoryProvider = Provider(
  (ref) => Vendorserviceupadate(),
);
final vendorServiceUploadUpdateProvider = FutureProvider.family
    .autoDispose<Map<String, dynamic>, (VendorServiceUploadModel, List<File>)>((
      ref,
      data,
    ) async {
      final repo = ref.read(vendorserviceupdateRepositoryProvider);
      return repo.vendorserviceupdate(
        ConstsApi.vendorserviceupload,
        data.$1,
        data.$2,
      );
    });

final vendorexpiredPlanRepositoryProvider = Provider(
  (ref) => VendorExpiredPlanRepository(),
);

final vendorexpiredPlanProvider = FutureProvider.autoDispose<ExpiredPlanModel>((
  ref,
) async {
  final repo = ref.read(vendorexpiredPlanRepositoryProvider);
  return repo.fetchvendorExpiredPlan(ConstsApi.expiredplan);
});
final catDeleteRepositoryProvider = Provider(
  (ref) => CatManagementDeleteRepository(),
);

// Provider for delete operation
final deleteCategoryProvider = FutureProvider.family.autoDispose<bool, String>((
  ref,
  categoryId,
) async {
  final repo = ref.read(catDeleteRepositoryProvider);
  return repo.deleteCategoryManagement(
    ConstsApi.catmangementdelete,
    categoryId,
  );
});

final ServiceDeleteRepositoryProvider = Provider(
  (ref) => SerciceDeleteRepository(),
);

// Provider for delete operation
final deleteserviceProvider = FutureProvider.family.autoDispose<bool, String>((
  ref,
  id,
) async {
  final repo = ref.read(ServiceDeleteRepositoryProvider);
  return repo.deleteService(ConstsApi.servicedelete, id);
});

final profilegetvendorRepositoryProvider = Provider(
  (ref) => ProfilegetvendorRepository(),
);

final profilegetvendorProvider =
    FutureProvider.autoDispose<List<ProfileGetModel>>((ref) async {
      final repo = ref.read(profilegetvendorRepositoryProvider);
      return repo.fetchprofilegetvendor(ConstsApi.vendorprofileget);
    });

final profileupdatevendorRepositoryProvider = Provider(
  (ref) => ProfileupdatevendorRepository(),
);

final profileupdatevendorProvider =
    FutureProvider.autoDispose<List<VendorProfileModel>>((ref) async {
      final repo = ref.read(profileupdatevendorRepositoryProvider);
      return repo.fetchProfileupdatevendor(ConstsApi.upadatevendorprofile);
    });

final termsAndConditionsRepositoryProvider = Provider(
  (ref) => TermsAndConditionsRepository(),
);

final termsAndConditionsProvider =
    FutureProvider.autoDispose<TermsAndConditionsModel>((ref) async {
      final repo = ref.read(termsAndConditionsRepositoryProvider);
      return repo.fetchTermsAndCondition(ConstsApi.termsandcondition);
    });

final privacypolicyRepositoryProvider = Provider(
  (ref) => PrivacypolicyRepository(),
);

final privacypolicyProvider =
    FutureProvider.autoDispose<TermsAndConditionsModel>((ref) async {
      final repo = ref.read(privacypolicyRepositoryProvider);
      return repo.fetchPrivacypolicy(ConstsApi.privacypolicy);
    });

final notificationRepositoryProvider = Provider(
  (ref) => NotificationRepository(),
);

final notificationProvider = FutureProvider.family
    .autoDispose<List<NotificationModel>, ({int type, String userId})>((
      ref,
      params,
    ) async {
      final repo = ref.read(notificationRepositoryProvider);
      return repo.fetchNotification(type: params.type, userId: params.userId);
    });

Future<void> updateNotificationCount(
  WidgetRef ref, {
  required int type,
  required String userId,
}) async {
  final repo = ref.read(notificationRepositoryProvider);
  final notifications = await repo.fetchNotification(
    type: type,
    userId: userId,
  );
  ref.read(notificationCountProvider.notifier).state = notifications.length;
}
