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

import 'package:bookmywages/model/Banner_model.dart';
import 'package:bookmywages/model/Booking_model.dart';
import 'package:bookmywages/model/Categories_model.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/login_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/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'
    show UserBookingDetails;
import 'package:bookmywages/model/vendor_model/terms_and_conditions_model.dart';
import 'package:bookmywages/model/vendor_model/vendor_booking_model.dart';
import 'package:bookmywages/model/vendor_model/vendor_catgories_model.dart'
    show VendorCategoriesModel;
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/viewmodel/consts_api.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http_parser/http_parser.dart'; // Add this at the top

class AuthRepository {
  Future<Map<String, dynamic>> loginUser(
    String url,
    LoginModel loginModel,
  ) async {
    try {
      final response = await http.post(
        Uri.parse(url),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode(loginModel.toJson()),
      );

      if (response.statusCode == 200) {
        final decoded = jsonDecode(response.body);
        print('Decoded Response: $decoded'); // Debug print

        dynamic data = decoded['data'];
        String userId = '';
        String isverify = '';

        // Handle different response structures
        if (data is List && data.isNotEmpty) {
          // Response contains a list of data
          userId = data[0]['id']?.toString() ?? '';
          isverify = data[0]['is_verified']?.toString() ?? '';
        } else if (data is Map) {
          // Response contains a single data object
          userId = data['id']?.toString() ?? '';
          isverify = data['is_verified']?.toString() ?? '';

          // Check if vendor_id exists in the data map
        } else {
          throw Exception('Unexpected response structure: $data');
        }

        // Store both values in SharedPreferences
        final prefs = await SharedPreferences.getInstance();
        await prefs.setString('userId', userId);
        await prefs.setString('is_verified', isverify);

        // Also store the full data JSON string for other operations
        await prefs.setString('data', userId);

        return decoded;
      } else {
        throw Exception(
          'Login failed with status code ${response.statusCode}: ${response.body}',
        );
      }
    } catch (e) {
      print('Login error: $e');
      throw Exception('Login failed: $e');
    }
  }

  Future<Map<String, dynamic>> registerUser(
    String url,
    Map<String, dynamic> data,
  ) async {
    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode(data),
    );

    if (response.statusCode == 200) {
      final decoded = jsonDecode(response.body);
      print('Decoded Response: $decoded'); // Debug print

      dynamic data = decoded['data'];

      String userId;
      String isverify;

      if (data is List && data.isNotEmpty) {
        userId = data[0]['id'].toString();
        isverify = data[0]['is_verified'].toString();
      } else if (data is Map && data.containsKey('id')) {
        userId = data['id'].toString();
        isverify = data['is_verified'].toString();
      } else {
        throw Exception('Unexpected response structure: $data');
      }

      final prefs = await SharedPreferences.getInstance();
      await prefs.setString('userId', userId);
      await prefs.setString('is_verified', isverify);

      return decoded;
    } else {
      throw Exception('Register failed: ${response.body}');
    }
  }

  // Add to AuthRepository class
  Future<Map<String, dynamic>> verifyOtp(String url, OtpModel otpModel) async {
    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode(otpModel.toJson()),
    );

    if (response.statusCode == 200) {
      final decoded = jsonDecode(response.body);
      print('OTP Verify Response: $decoded');

      // Directly store is_verified = '1'
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString('is_verified', '1');

      return decoded;
    } else {
      throw Exception('OTP verification failed: ${response.body}');
    }
  }
}

class BannerRepository {
  Future<List<BannerModel>> fetchBanners(String url) async {
    try {
      final response = await http
          .get(Uri.parse(url))
          .timeout(const Duration(seconds: 10));

      if (response.statusCode == 200) {
        final jsonBody = jsonDecode(response.body);
        final List<dynamic> bannerList = jsonBody['data'] ?? [];
        return bannerList.map((json) => BannerModel.fromJson(json)).toList();
      } else {
        return []; // return empty list on server error
      }
    } catch (_) {
      return []; // return empty list on timeout or any error
    }
  }
}

class CategoryRepository {
  Future<List<CategoriesModel>> fetchCategories(String url) async {
    final response = await http.get(Uri.parse(url));

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> categoryList = jsonBody['data'] ?? [];

      return categoryList
          .map((json) => CategoriesModel.fromJson(json))
          .toList();
    } else {
      throw Exception('Failed to load categories');
    }
  }
}

class packageRepository {
  Future<List<PackageModel>> fetchpackage(String url) async {
    final response = await http.get(Uri.parse(url));

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> packagelist = jsonBody['data'] ?? [];

      return packagelist.map((json) => PackageModel.fromJson(json)).toList();
    } else {
      throw Exception('Failed to load categories');
    }
  }
}

class SubcategoryRepository {
  Future<List<SubcategoryModel>> fetchSubcategories(
    String url,
    String categoryId,
  ) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'userId': userId, 'category': categoryId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => SubcategoryModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load subcategories');
    }
  }
}

class ProfilegetRepository {
  Future<List<ProfileGetModel>> fetchprofileget(String url) async {
    // Retrieve userId from SharedPreferences
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    // Debugging: Print the userId to make sure it's correct
    print('User ID: $userId');

    // Check if userId is available before making the request
    if (userId.isEmpty) {
      throw Exception('User ID is not available.');
    }

    // Send the userId in the API request
    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    // Check if the response status code is successful
    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];

      // Convert the JSON response to a list of ProfileGetModel objects
      return list.map((e) => ProfileGetModel.fromJson(e)).toList();
    } else {
      // Handle API errors
      throw Exception(
        'Failed to load profile data, status code: ${response.statusCode}',
      );
    }
  }
}

class ServiceRepository {
  Future<List<ServiceModel>> fetchService(
    String url,
    String categoryId, [
    String? subcategoryId,
    String? selecttype, // Optional parameter in square brackets
  ]) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    // Create the request body
    Map<String, dynamic> requestBody = {
      'user_id': userId,
      'category': categoryId,
    };

    // Add subcategory only if it's provided
    if (subcategoryId != null && subcategoryId.isNotEmpty) {
      requestBody['subcategory'] = subcategoryId;
    }
    if (selecttype != null && selecttype.isNotEmpty) {
      requestBody['service_type'] = selecttype;
    }
    print('Request Body: $requestBody'); // Debug log

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode(requestBody),
    );

    if (response.statusCode == 200) {
      print('Response: ${response.body}'); // Debug log
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => ServiceModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load services: ${response.statusCode}');
    }
  }
}

class ProfileupdateRepository {
  Future<List<ProfileGetModel>> fetchprofileupdate(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    if (userId.isEmpty) throw Exception('User ID is not available.');

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => ProfileGetModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load profile, code: ${response.statusCode}');
    }
  }

  Future<void> updateProfile({
    required String url,
    required String name,
    required String number,
    required String email,
    required String address,
    File? imageFile,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final request = http.MultipartRequest('POST', Uri.parse(url));
    request.fields['user_id'] = userId;
    request.fields['name'] = name;
    request.fields['number'] = number;
    request.fields['email'] = email;
    request.fields['address'] = address;

    if (imageFile != null) {
      request.files.add(
        await http.MultipartFile.fromPath(
          'profile_pic', // Make sure this matches your backend key
          imageFile.path,
          contentType: MediaType('image', 'jpeg'), // Optional but recommended
        ),
      );
    }

    final response = await request.send();

    if (response.statusCode != 200) {
      throw Exception('Failed to update profile');
    }
  }
}

class GetReviewRepository {
  Future<List<GetReviewModel>> fetchgetreview(
    String url,
    String serviceId,
  ) async {
    Map<String, dynamic> requestBody = {'service_id': serviceId};
    print('Request Body: $requestBody');

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode(requestBody),
    );

    if (response.statusCode == 200) {
      print('Response: ${response.body}');
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => GetReviewModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load reviews: ${response.statusCode}');
    }
  }
}

class MostPopularRepository {
  Future<List<MostPopularModel>> fetchMostPopular(
    String url,
    String categoryId,
  ) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    Map<String, dynamic> requestBody = {
      'user_id': userId,
      'category': categoryId,
    };

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode(requestBody),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => MostPopularModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load services: ${response.statusCode}');
    }
  }
}

class EnquriyRepository {
  Future<List<EnquiryModel>> fetchenquriy(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    if (userId.isEmpty) throw Exception('User ID is not available.');

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => EnquiryModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load profile, code: ${response.statusCode}');
    }
  }

  Future<void> updateEnquriy({
    required BuildContext context,
    required String url,
    required String name,
    required String number,
    required String email,
    required String message,
    required String serviceid,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final request = http.MultipartRequest('POST', Uri.parse(url));
    request.fields['user_id'] = userId;
    request.fields['name'] = name;
    request.fields['mobile'] = number;
    request.fields['email'] = email;
    request.fields['message'] = message;
    request.fields['service_id'] = serviceid;

    final response = await request.send();
    if (response.statusCode == 200) {
      Fluttertoast.showToast(
        msg: "Enquiry Successful",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
    } else {
      Fluttertoast.showToast(
        msg: "Failed to update profile",
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
      );
      throw Exception('Failed to update profile');
    }
  }
}

class BookingRepository {
  Future<List<BookingModel>> fetchBooking(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    if (userId.isEmpty) throw Exception('User ID is not available.');

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => BookingModel.fromJson(e)).toList();
    } else {
      throw Exception(
        'Failed to load booking data. Code: ${response.statusCode}',
      );
    }
  }

  Future<void> updateBooking({
    required BuildContext context,
    required String url,
    required String name,
    required String number,
    required String email,
    required String message,
    required String address,
    required String date,
    required String time,
    required String serviceId,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    if (userId.isEmpty) {
      Fluttertoast.showToast(
        msg: "User ID not found",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
      return;
    }

    final request = http.MultipartRequest('POST', Uri.parse(url));
    request.fields['user_id'] = userId;
    request.fields['name'] = name;
    request.fields['mobile_number'] = number;
    request.fields['email'] = email;
    request.fields['message'] = message;
    request.fields['service_id'] = serviceId;
    request.fields['address'] = address;
    request.fields['service_date'] = date;
    request.fields['service_time'] = time;

    final response = await request.send();
    final responseBody = await response.stream.bytesToString();
    final jsonResponse = jsonDecode(responseBody);

    if (response.statusCode == 200) {
      Fluttertoast.showToast(
        msg: "Booking Successful",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
    } else if (response.statusCode == 404 &&
        jsonResponse['data'] == 'You can book maximum 1 services.') {
      Fluttertoast.showToast(
        msg: jsonResponse['data'],
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
      );
    } else {
      Fluttertoast.showToast(
        msg:
            jsonResponse['data'] ??
            'Failed to submit enquiry. Code: ${response.statusCode}',
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
      );
      throw Exception('Failed to update booking');
    }
  }
}

// ignore: camel_case_types
class updatereviewRepository {
  Future<List<GetReviewModel>> updatereview(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    if (userId.isEmpty) throw Exception('User ID is not available.');

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => GetReviewModel.fromJson(e)).toList();
    } else {
      throw Exception(
        'Failed to load booking data. Code: ${response.statusCode}',
      );
    }
  }

  Future<void> updatereviews({
    required BuildContext context,
    required String url,
    required String review,
    required String serviceId,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    if (userId.isEmpty) {
      Fluttertoast.showToast(
        msg: "User ID not found",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
      return;
    }

    final request = http.MultipartRequest('POST', Uri.parse(url));
    request.fields['user_id'] = userId;
    request.fields['review'] = review;

    request.fields['service_id'] = serviceId;

    final response = await request.send();
    final responseBody = await response.stream.bytesToString();
    final jsonResponse = jsonDecode(responseBody);

    if (response.statusCode == 200) {
      Fluttertoast.showToast(
        msg: "Review submitted successfully",
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
        backgroundColor: Colors.green,
        textColor: Colors.white,
      );
    } else {
      Fluttertoast.showToast(
        msg:
            jsonResponse['data'] ??
            'Failed to submit review. Code: ${response.statusCode}',
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
        backgroundColor: Colors.red,
        textColor: Colors.white,
      );
      throw Exception('Failed to update review');
    }
  }
}

class enquriylistRepository {
  Future<List<EnquiryListModel>> fetchenquirylist(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    if (userId.isEmpty) throw Exception('User ID is not available.');

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => EnquiryListModel.fromJson(e)).toList();
    } else {
      throw Exception(
        'Failed to load booking data. Code: ${response.statusCode}',
      );
    }
  }
}

class EnquriydeleteRepository {
  Future<bool> enquriydelete(String url, String id) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId, 'id': id}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      // Assuming your API returns a success flag or message
      // Adjust this based on your actual API response
      return jsonBody['success'] == true ||
          jsonBody['status'] == 'success' ||
          jsonBody['message']?.toLowerCase().contains('success') == true;
    } else {
      throw Exception('Failed to delete enquiry');
    }
  }
}

class PaymentdetailsRepository {
  Future<List<PaymentDetailsModel>> fetchpayment(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);

      final List<dynamic> dataList = jsonBody['data'] ?? [];
      return dataList
          .map((json) => PaymentDetailsModel.fromJson(json))
          .toList();
    } else {
      throw Exception('Failed to fetch payment details');
    }
  }
}

class PaymentdeleteRepository {
  Future<bool> paymentdelete(String url, String id) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId, 'id': id}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      // Assuming your API returns a success flag or message
      // Adjust this based on your actual API response
      return jsonBody['success'] == true ||
          jsonBody['status'] == 'success' ||
          jsonBody['message']?.toLowerCase().contains('success') == true;
    } else {
      throw Exception('Failed to delete payment Details');
    }
  }
}

class ChangepasswordRepository {
  Future<bool> changepassword(String url, String password) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId, 'password': password}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      // Assuming your API returns a success flag or message
      // Adjust this based on your actual API response
      return jsonBody['success'] == true ||
          jsonBody['status'] == 'success' ||
          jsonBody['message']?.toLowerCase().contains('success') == true;
    } else {
      throw Exception('Failed to  changepassword');
    }
  }
}

class UserhistoryBookingdetailsRepository {
  Future<List<UserBookingDetails>> fetchhistorybooking(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      print(response.body);
      print(jsonBody);

      final List<dynamic> dataList = jsonBody['data'] ?? [];
      return dataList.map((json) => UserBookingDetails.fromJson(json)).toList();
    } else {
      throw Exception('Failed to fetch payment details');
    }
  }
}

class CancelbookingRepository {
  Future<bool> cancelbooking({
    required String url,
    required String id,
    required String serviceId,
    required String type,
  }) async {
    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'id': id, 'service_id': serviceId, 'type': type}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      return jsonBody['success'] == true ||
          jsonBody['status'] == 'success' ||
          jsonBody['message']?.toLowerCase().contains('success') == true;
    } else {
      throw Exception('Failed to cancel booking');
    }
  }
}

class BookingmodifyRepository {
  Future<bool> bookingmodify({
    required String url,
    required String id,
    required String serviceId,
    required String servicedate,
    required String servicetime,
  }) async {
    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({
        'id': id,
        'service_id': serviceId,
        'service_date': servicedate,
        'service_time': servicetime,
      }),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      return jsonBody['success'] == true ||
          jsonBody['status'] == 'success' ||
          jsonBody['message']?.toLowerCase().contains('success') == true;
    } else {
      throw Exception('Failed to  modify');
    }
  }
}

class ExpiredPlanRepository {
  Future<ExpiredPlanModel> fetchExpiredPlan(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final Map<String, dynamic> data = jsonBody['data'] ?? {};
      return ExpiredPlanModel.fromJson(data);
    } else {
      throw Exception('Failed to fetch expired plan');
    }
  }
}

class PlanSuccessRepository {
  Future<bool> planSuccess({
    required String url,
    required String userId,
    required String planId,
    required int duration,
    required int type,
  }) async {
    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({
        'user_id': userId,
        'plan_id': planId,
        'duration': duration.toString(),
        'type': type.toString(),
      }),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      return jsonBody['success'] == true ||
          jsonBody['status'] == 'success' ||
          jsonBody['message']?.toLowerCase().contains('success') == true;
    } else {
      throw Exception('Failed to subscribe to plan');
    }
  }
}

////vendor flow
class GetvendorId {
  Future fetchGetid(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final data = jsonBody['data'];

      // Extract and store vendor_id and vendor_status if not null
      if (data != null) {
        final vendorId = data['vendor_id']?.toString() ?? '';
        final vendorStatus = data['vendor_status']?.toString() ?? '';

        await prefs.setString('vendor_id', vendorId);
        await prefs.setString('vendor_status', vendorStatus);

        print('Stored vendor_id: $vendorId');
        print('Stored vendor_status: $vendorStatus');
      }

      return data;
    } else {
      throw Exception('Failed to fetch vendor data');
    }
  }
}

class VendorRegister {
  Future<Map<String, dynamic>> vendorRegister(
    String url,
    VendorRegisterModel vendorModel,
  ) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('userId') ?? '';

    vendorModel.userId = userId; // inject userId into the model

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode(vendorModel.toJson()),
    );

    if (response.statusCode == 200) {
      final decoded = jsonDecode(response.body);
      print('Decoded Response: $decoded');
      return decoded;
    } else {
      throw Exception('Register failed: ${response.body}');
    }
  }
}

class VendorGetProfile {
  Future<Map<String, dynamic>> vendorGetProfile(String url) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final dataId = prefs.getString('vendor_id') ?? '';

      if (dataId.isEmpty) {
        throw Exception('Data ID not found in SharedPreferences.');
      }

      final body = jsonEncode({'dataId': dataId});

      final response = await http.post(
        Uri.parse(url),
        headers: {'Content-Type': 'application/json'},
        body: body,
      );

      if (response.statusCode == 200) {
        final decoded = jsonDecode(response.body);
        print('Decoded Response: $decoded');
        return decoded; // Return the decoded response directly
      } else {
        throw Exception(
          'Get profile failed with status ${response.statusCode}: ${response.body}',
        );
      }
    } catch (e) {
      print('Error in vendorGetProfile: $e');
      rethrow;
    }
  }
}

class Vendorserviceupload {
  Future<Map<String, dynamic>> vendorserviceupload(
    String url,
    VendorServiceUploadModel serviceupload,
    List<File> images,
  ) async {
    try {
      // Create a multipart request for uploading files and data
      var request = http.MultipartRequest('POST', Uri.parse(url));

      // Add service data as fields
      request.fields['vendor_id'] = serviceupload.id;
      request.fields['vendorname'] = serviceupload.vendorName;
      request.fields['servicename'] = serviceupload.serviceName;
      request.fields['service_type'] = serviceupload.serviceType;
      request.fields['category'] = serviceupload.category;
      request.fields['subcategory'] = serviceupload.subcategory;
      request.fields['workinghours'] = serviceupload.workingHours;
      request.fields['workingduration'] = serviceupload.workingDuration;
      request.fields['amount'] = serviceupload.amount.toString();
      request.fields['location'] = serviceupload.location;
      request.fields['description'] = serviceupload.description ?? '';
      request.fields['details'] = serviceupload.details;

      // Add video links as JSON array
      if (serviceupload.videos.isNotEmpty) {
        request.fields['videos'] = jsonEncode(serviceupload.videos);
      }

      // Add images as files with array notation
      for (int i = 0; i < images.length; i++) {
        final file = images[i];
        final fileName =
            'image_${i}_${DateTime.now().millisecondsSinceEpoch}.jpg';

        // Get file extension from path
        String extension = file.path.split('.').last.toLowerCase();
        String mimeType = 'image/jpeg'; // Default

        // Set correct mime type based on extension
        if (extension == 'png') {
          mimeType = 'image/png';
        } else if (extension == 'jpg' || extension == 'jpeg') {
          mimeType = 'image/jpeg';
        } else if (extension == 'gif') {
          mimeType = 'image/gif';
        } else if (extension == 'webp') {
          mimeType = 'image/webp';
        }

        // Add the file to the request with indexed array notation
        request.files.add(
          http.MultipartFile(
            'images[$i]', // Indexed array notation for multiple images
            file.readAsBytes().asStream(),
            file.lengthSync(),
            filename: fileName,
            contentType: MediaType.parse(mimeType),
          ),
        );
      }

      // Send the request
      var streamedResponse = await request.send();
      var response = await http.Response.fromStream(streamedResponse);

      // Parse response regardless of status code
      try {
        final decoded = jsonDecode(response.body) as Map<String, dynamic>;
        print('Decoded Response: $decoded');

        // Check if request was successful
        if (response.statusCode == 200 || response.statusCode == 201) {
          return decoded;
        } else {
          // For failed requests, extract error message
          String errorMessage =
              decoded['data']?.toString() ??
              decoded['message']?.toString() ??
              'Upload failed with status: ${response.statusCode}';

          // Return the error response for handling upstream
          return {
            'success': false,
            'error': errorMessage,
            'statusCode': response.statusCode,
            'data': decoded,
          };
        }
      } catch (jsonError) {
        // If JSON parsing fails, use raw response
        String errorMessage =
            'Request failed with status: ${response.statusCode}. Response: ${response.body}';

        Fluttertoast.showToast(
          msg: 'Server response error',
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.BOTTOM,
        );

        throw Exception(errorMessage);
      }
    } on SocketException catch (e) {
      String errorMessage = 'No internet connection: ${e.message}';
      Fluttertoast.showToast(
        msg: 'No internet connection',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
      throw Exception(errorMessage);
    } on http.ClientException catch (e) {
      String errorMessage = 'Network error: ${e.message}';
      Fluttertoast.showToast(
        msg: 'Network error occurred',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
      throw Exception(errorMessage);
    } on FormatException catch (e) {
      String errorMessage = 'Invalid response format: ${e.message}';
      Fluttertoast.showToast(
        msg: 'Invalid server response',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
      throw Exception(errorMessage);
    } catch (e) {
      String errorMessage = 'Unexpected error: $e';
      Fluttertoast.showToast(
        msg: 'Something went wrong',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
      );
      throw Exception(errorMessage);
    }
  }
}

class VendorbookingdetailsRepository {
  Future<List<VendorBookingModel>> fetchvendorbooking(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('vendor_id') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'vendor_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      print(response.body);
      print(jsonBody);

      final List<dynamic> dataList = jsonBody['data'] ?? [];
      return dataList.map((json) => VendorBookingModel.fromJson(json)).toList();
    } else {
      throw Exception('Failed to fetch booking details');
    }
  }
}

class ChangebookingstatusRepository {
  Future<bool> changebooking({
    required String url,
    required String id,
    required String status,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('vendor_id') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'id': id, 'user_id': userId, 'status': status}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      return jsonBody['success'] == true ||
          jsonBody['status'] == 'success' ||
          jsonBody['message']?.toLowerCase().contains('success') == true;
    } else {
      throw Exception('Failed to update booking status');
    }
  }
}

class VendorcatgoriesRepository {
  Future<List<VendorCategoriesModel>> fetchvendorcat(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('vendor_id') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'vendor_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);

      final List<dynamic> dataList = jsonBody['data'] ?? [];
      return dataList
          .map((json) => VendorCategoriesModel.fromJson(json))
          .toList();
    } else {
      throw Exception('Failed to fetch booking details');
    }
  }
}

class VendorserviceRepository {
  Future<List<VendorServiceModel>> fetchvendorservice(String url) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final userId = prefs.getString('vendor_id') ?? '';

      if (userId.isEmpty) {
        throw Exception('Vendor ID not found in SharedPreferences');
      }

      final response = await http.post(
        Uri.parse(url),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({'vendor_id': userId}),
      );

      if (response.statusCode == 200) {
        final jsonBody = jsonDecode(response.body);

        // Add more detailed logging

        if (jsonBody['data'] == null) {
          return [];
        }

        final List<dynamic> dataList = jsonBody['data'] ?? [];
        return dataList
            .map((json) => VendorServiceModel.fromJson(json))
            .toList();
      } else {
        throw Exception(
          'Failed to fetch service details: ${response.statusCode}',
        );
      }
    } catch (e) {
      throw Exception('Failed to fetch service details: $e');
    }
  }
}

// Updated API Service Class
class Vendorserviceupadate {
  Future<Map<String, dynamic>> vendorserviceupdate(
    String url,
    VendorServiceUploadModel serviceupload,
    List<File> newImages,
  ) async {
    try {
      var request = http.MultipartRequest('POST', Uri.parse(url));

      // Add all basic fields
      request.fields.addAll({
        'id': serviceupload.id,
        'vendorname': serviceupload.vendorName,
        'servicename': serviceupload.serviceName,
        'service_type': serviceupload.serviceType,
        'category': serviceupload.category,
        'subcategory': serviceupload.subcategory,
        'workinghours': serviceupload.workingHours,
        'workingduration': serviceupload.workingDuration,
        'amount': serviceupload.amount.toString(),
        'location': serviceupload.location,
        'description': serviceupload.description ?? '',
        'details': serviceupload.details,
      });

      // Handle videos - send as JSON string
      if (serviceupload.videos.isNotEmpty) {
        request.fields['videos'] = jsonEncode(serviceupload.videos);
        print('Videos JSON: ${request.fields['videos']}');
      }

      // Process ALL images (existing + new) as multipart files
      List<File> allImageFiles = [];

      // Step 1: Convert existing images (URLs) to files if needed
      if (serviceupload.images.isNotEmpty) {
        print('Processing ${serviceupload.images.length} existing images...');

        for (int i = 0; i < serviceupload.images.length; i++) {
          final imageUrl = serviceupload.images[i];
          print('Processing existing image $i: $imageUrl');

          try {
            // If it's already a local file path
            if (imageUrl.startsWith('/') || imageUrl.startsWith('file://')) {
              final file = File(imageUrl.replaceFirst('file://', ''));
              if (await file.exists()) {
                allImageFiles.add(file);
              } else {
                print('⚠ Existing file not found: ${file.path}');
              }
            }
            // If it's a URL, download it
            else if (imageUrl.startsWith('http')) {
              final downloadedFile = await _downloadImageAsFile(imageUrl, i);
              if (downloadedFile != null) {
                allImageFiles.add(downloadedFile);
                print(
                  '✓ Downloaded and added existing image: ${downloadedFile.path}',
                );
              } else {
                print('⚠ Failed to download existing image: $imageUrl');
              }
            }
            // If it's a relative path or asset
            else {
              print('⚠ Unsupported existing image format: $imageUrl');
            }
          } catch (e) {
            print('⚠ Error processing existing image $imageUrl: $e');
          }
        }
      }

      // Step 2: Add new images to the list
      allImageFiles.addAll(newImages);

      print('Total images to upload: ${allImageFiles.length}');

      // Step 3: Upload all images with same field name 'images[]'
      if (allImageFiles.isNotEmpty) {
        print('Processing ${allImageFiles.length} total images for upload...');

        for (int i = 0; i < allImageFiles.length; i++) {
          final file = allImageFiles[i];

          // Validate file exists
          if (!await file.exists()) {
            print('WARNING: File does not exist: ${file.path}');
            continue;
          }

          // Get file info
          final fileSize = await file.length();
          final fileName = file.path.split('/').last;
          final extension = fileName.split('.').last.toLowerCase();

          print('Processing file $i: $fileName ($fileSize bytes)');

          // Validate file size (5MB limit)
          if (fileSize > 5 * 1024 * 1024) {
            continue;
          }

          // Determine MIME type
          String mimeType;
          switch (extension) {
            case 'png':
              mimeType = 'image/png';
              break;
            case 'jpg':
            case 'jpeg':
              mimeType = 'image/jpeg';
              break;
            case 'gif':
              mimeType = 'image/gif';
              break;
            case 'webp':
              mimeType = 'image/webp';
              break;
            default:
              mimeType = 'image/jpeg';
          }

          // Create unique filename for upload
          final uploadFileName =
              'upload_${DateTime.now().millisecondsSinceEpoch}_$i.$extension';

          try {
            // Method 1: Try fromPath (preferred)
            var multipartFile = await http.MultipartFile.fromPath(
              'images[]', // All images use same field name
              file.path,
              filename: uploadFileName,
              contentType: MediaType.parse(mimeType),
            );

            request.files.add(multipartFile);
          } catch (fromPathError) {
            // Method 2: Fallback to fromBytes
            try {
              final bytes = await file.readAsBytes();
              var multipartFile = http.MultipartFile.fromBytes(
                'images[]',
                bytes,
                filename: uploadFileName,
                contentType: MediaType.parse(mimeType),
              );

              request.files.add(multipartFile);
              // ignore: empty_catches
            } catch (fromBytesError) {}
          }
        }
      } else {
        print('No images to upload');
      }

      // Add headers
      request.headers.addAll({
        'Accept': 'application/json',
        'Content-Type': 'multipart/form-data',
      });

      // Debug request info
      print('=== REQUEST SUMMARY ===');
      print('Fields: ${request.fields.keys.toList()}');
      print('Files: ${request.files.length}');
      for (var file in request.files) {
        print(
          '  - Field: ${file.field}, Filename: ${file.filename}, Length: ${file.length}',
        );
      }

      // Send request with timeout
      print('Sending request...');
      var streamedResponse = await request.send().timeout(
        Duration(seconds: 120), // 2 minute timeout for large uploads
        onTimeout: () {
          throw TimeoutException('Upload timeout after 2 minutes');
        },
      );

      var response = await http.Response.fromStream(streamedResponse);

      print('=== RESPONSE INFO ===');
      print('Status Code: ${response.statusCode}');
      print('Response Headers: ${response.headers}');
      print('Response Body Length: ${response.body.length}');
      print(
        'Response Body Preview: ${response.body.length > 500 ? "${response.body.substring(0, 500)}..." : response.body}',
      );

      // Handle response
      if (response.statusCode >= 200 && response.statusCode < 300) {
        try {
          final decoded = jsonDecode(response.body) as Map<String, dynamic>;
          print('✓ Successfully parsed JSON response');
          return decoded;
        } catch (jsonError) {
          print('⚠ JSON parsing failed: $jsonError');
          // Return success with raw response if JSON parsing fails but status is OK
          return {
            'success': true,
            'message': 'Update completed successfully',
            'raw_response': response.body,
          };
        }
      } else {
        // Handle error response
        String errorMessage;
        try {
          final errorResponse = jsonDecode(response.body);
          errorMessage =
              errorResponse['message'] ??
              errorResponse['error'] ??
              'Server returned status ${response.statusCode}';
        } catch (e) {
          errorMessage =
              'Server error (${response.statusCode}): ${response.body}';
        }

        print('✗ Server error: $errorMessage');
        throw Exception(errorMessage);
      }
    } on TimeoutException catch (e) {
      print('✗ Timeout error: $e');
      throw Exception(
        'Upload timeout. Please check your connection and try again.',
      );
    } on SocketException catch (e) {
      print('✗ Network error: $e');
      throw Exception('Network error. Please check your internet connection.');
    } on http.ClientException catch (e) {
      print('✗ HTTP client error: $e');
      throw Exception('Connection error: ${e.message}');
    } catch (e) {
      print('✗ Unexpected error: $e');
      rethrow;
    }
  }

  // Helper method to download existing images from URLs
  Future<File?> _downloadImageAsFile(String imageUrl, int index) async {
    try {
      final response = await http.get(Uri.parse(imageUrl));

      if (response.statusCode == 200) {
        // Get app's temporary directory
        final directory = await getTemporaryDirectory();

        // Determine file extension from URL or content type
        String extension = 'jpg';
        if (imageUrl.contains('.png')) {
          extension = 'png';
        } else if (imageUrl.contains('.gif'))
          extension = 'gif';
        else if (imageUrl.contains('.webp'))
          extension = 'webp';
        else if (response.headers['content-type']?.contains('png') == true)
          extension = 'png';

        // Create temporary file
        final fileName =
            'existing_image_${index}_${DateTime.now().millisecondsSinceEpoch}.$extension';
        final file = File('${directory.path}/$fileName');

        // Write downloaded bytes to file
        await file.writeAsBytes(response.bodyBytes);

        return file;
      } else {
        print('Failed to download image: ${response.statusCode}');
        return null;
      }
    } catch (e) {
      print('Error downloading image $imageUrl: $e');
      return null;
    }
  }
}

// Image Upload Helper Class
class ImageUploadHelper {
  static Future<List<File>> pickMultipleImages() async {
    try {
      final picker = ImagePicker();
      final List<XFile> pickedFiles = await picker.pickMultiImage(
        maxWidth: 1920,
        maxHeight: 1920,
        imageQuality: 85,
      );

      List<File> validFiles = [];

      for (XFile xFile in pickedFiles) {
        File file = File(xFile.path);

        if (await validateImageFile(file)) {
          validFiles.add(file);
        } else {
          print('Invalid image file: ${xFile.name}');
        }
      }

      return validFiles;
    } catch (e) {
      print('Error picking images: $e');
      return [];
    }
  }

  static Future<bool> validateImageFile(File file) async {
    try {
      if (!await file.exists()) {
        print('File does not exist: ${file.path}');
        return false;
      }

      // Check file size (max 5MB)
      int fileSize = await file.length();
      if (fileSize > 5 * 1024 * 1024) {
        print('File too large: ${file.path} ($fileSize bytes)');
        return false;
      }

      // Check file extension
      String extension = file.path.split('.').last.toLowerCase();
      List<String> validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];

      if (!validExtensions.contains(extension)) {
        print('Invalid file extension: $extension');
        return false;
      }

      return true;
    } catch (e) {
      print('Error validating file: $e');
      return false;
    }
  }
}

class VendorExpiredPlanRepository {
  Future<ExpiredPlanModel> fetchvendorExpiredPlan(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('vendor_id') ?? '';

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'user_id': userId}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final Map<String, dynamic> data = jsonBody['data'] ?? {};
      return ExpiredPlanModel.fromJson(data);
    } else {
      throw Exception('Failed to fetch expired plan');
    }
  }
}

class DetailpageRepository {
  Future<List<DetailPageModel>> fetchDetailpage(
    String url,
    int serviceid,
  ) async {
    final response = await http.get(
      Uri.parse('$url?service_id=$serviceid'),
      headers: {'Content-Type': 'application/json'},
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final data = jsonBody['data'];

      // Handle single object or list
      if (data is List) {
        return data.map((e) => DetailPageModel.fromJson(e)).toList();
      } else if (data is Map<String, dynamic>) {
        return [DetailPageModel.fromJson(data)];
      } else {
        return [];
      }
    } else {
      throw Exception('Failed to load detail page');
    }
  }
}

class CatManagementDeleteRepository {
  Future<bool> deleteCategoryManagement(String url, String categoryId) async {
    final prefs = await SharedPreferences.getInstance();
    final vendorId = prefs.getString('vendor_id') ?? '';

    try {
      final response = await http.post(
        Uri.parse(url),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({'vendor_id': vendorId, 'category': categoryId}),
      );

      if (response.statusCode == 200) {
        final jsonBody = jsonDecode(response.body);
        return jsonBody['success'] == true ||
            jsonBody['status'] == 'success' ||
            jsonBody['message']?.toLowerCase().contains('success') == true;
      } else {
        throw Exception('Failed to delete category: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('Network error: $e');
    }
  }
}

class SerciceDeleteRepository {
  Future<bool> deleteService(String url, String id) async {
    final prefs = await SharedPreferences.getInstance();
    final vendorId = prefs.getString('vendor_id') ?? '';

    try {
      final response = await http.post(
        Uri.parse(url),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({'vendor_id': vendorId, 'id': id}),
      );

      if (response.statusCode == 200) {
        final jsonBody = jsonDecode(response.body);
        return jsonBody['success'] == true ||
            jsonBody['status'] == 'success' ||
            jsonBody['message']?.toLowerCase().contains('success') == true;
      } else {
        throw Exception('Failed to delete service: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception('Network error: $e');
    }
  }
}

class ProfilegetvendorRepository {
  Future<List<ProfileGetModel>> fetchprofilegetvendor(String url) async {
    // Retrieve userId from SharedPreferences
    final prefs = await SharedPreferences.getInstance();
    final vendorid = prefs.getString('vendor_id') ?? '';

    // Debugging: Print the userId to make sure it's correct
    print('vendor_id: $vendorid');

    // Check if userId is available before making the request
    if (vendorid.isEmpty) {
      throw Exception('User ID is not available.');
    }

    // Send the userId in the API request
    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'vendor_id': vendorid}),
    );

    // Check if the response status code is successful
    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];

      // Convert the JSON response to a list of ProfileGetModel objects
      return list.map((e) => ProfileGetModel.fromJson(e)).toList();
    } else {
      // Handle API errors
      throw Exception(
        'Failed to load profile data, status code: ${response.statusCode}',
      );
    }
  }
}

class ProfileupdatevendorRepository {
  Future<List<VendorProfileModel>> fetchProfileupdatevendor(String url) async {
    final prefs = await SharedPreferences.getInstance();
    final vendorid = prefs.getString('vendor_id') ?? '';

    if (vendorid.isEmpty) throw Exception('User ID is not available.');

    final response = await http.post(
      Uri.parse(url),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'vendor_id': vendorid}),
    );

    if (response.statusCode == 200) {
      final jsonBody = jsonDecode(response.body);
      final List<dynamic> list = jsonBody['data'] ?? [];
      return list.map((e) => VendorProfileModel.fromJson(e)).toList();
    } else {
      throw Exception('Failed to load profile, code: ${response.statusCode}');
    }
  }

  Future<void> updateProfilevendor({
    required String url,
    required String name,
    required String number,
    required String email,
    required String address,
    File? imageFile,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    final userId = prefs.getString('vendor_id') ?? '';

    final request = http.MultipartRequest('POST', Uri.parse(url));
    request.fields['vendor_id'] = userId;
    request.fields['name'] = name;
    request.fields['number'] = number;
    request.fields['email'] = email;
    request.fields['address'] = address;

    if (imageFile != null) {
      request.files.add(
        await http.MultipartFile.fromPath(
          'profile_pic', // Make sure this matches your backend key
          imageFile.path,
          contentType: MediaType('image', 'jpeg'), // Optional but recommended
        ),
      );
    }

    final response = await request.send();

    if (response.statusCode != 200) {
      throw Exception('Failed to update profile');
    }
  }
}

class TermsAndConditionsRepository {
  Future<TermsAndConditionsModel> fetchTermsAndCondition(String url) async {
    try {
      final response = await http.get(Uri.parse(url));

      if (response.statusCode == 200) {
        final jsonBody = jsonDecode(response.body);
        return TermsAndConditionsModel.fromJson(jsonBody);
      } else {
        throw Exception(
          'Failed to load terms and conditions, status code: ${response.statusCode}',
        );
      }
    } catch (e) {
      throw Exception('Failed to fetch terms and conditions: $e');
    }
  }
}

class PrivacypolicyRepository {
  Future<TermsAndConditionsModel> fetchPrivacypolicy(String url) async {
    try {
      final response = await http.get(Uri.parse(url));

      if (response.statusCode == 200) {
        final jsonBody = jsonDecode(response.body);
        return TermsAndConditionsModel.fromJson(jsonBody);
      } else {
        throw Exception(
          'Failed to load terms and conditions, status code: ${response.statusCode}',
        );
      }
    } catch (e) {
      throw Exception('Failed to fetch terms and conditions: $e');
    }
  }
}

class NotificationRepository {
  Future<List<NotificationModel>> fetchNotification({
    required int type,
    required String userId,
  }) async {
    try {
      final uri = Uri.parse(ConstsApi.notification);

      final response = await http.post(
        uri,
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({'type': type, 'user_id': userId}),
      );

      print('Fetching notification from: $uri');
      print('Status Code: ${response.statusCode}');
      print('Response Body: ${response.body}');

      if (response.statusCode == 200) {
        final jsonBody = jsonDecode(response.body);

        // Handle if data is inside "data" key
        if (jsonBody is Map && jsonBody['data'] is List) {
          final List dataList = jsonBody['data'];
          return dataList
              .map<NotificationModel>((e) => NotificationModel.fromJson(e))
              .toList();
        }

        // Handle if directly a List
        if (jsonBody is List) {
          return jsonBody
              .map<NotificationModel>((e) => NotificationModel.fromJson(e))
              .toList();
        }

        return []; // no recognizable data
      } else {
        throw Exception('Status Code: ${response.statusCode}');
      }
    } catch (e) {
      print('Error fetching notification: $e');
      throw Exception('Failed to fetch notification: $e');
    }
  }
}
