import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import '../../domain/provider/product/all_products.dart';
import '../../modules/product/product.dart';

class ProductsController extends GetxController {
  final ProductsProvider provider = ProductsProvider();
  var isConnected = true.obs;
  var isLoading = false.obs;
  var productResponse = Rxn<ProductResponse>();
  var selectedIndex = 0.obs;
  var searchQuery = ''.obs;
  var isSearching = false.obs;

  /// In-memory cache: key is "categoryId_tenantId"
  final Map<String, ProductResponse> _cache = {};

  @override
  void onInit() {
    super.onInit();


    // Listen for connectivity changes
    Connectivity().onConnectivityChanged.listen((status) {
      isConnected.value = (status != ConnectivityResult.none);
    });

  }
  Future<bool> hasInternet() async {
    try {
      final response = await http.get(Uri.parse('https://www.google.com'))
          .timeout(const Duration(seconds: 5));

      if (response.statusCode == 200) {
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  }



  Future<void> fetchProducts(int categoryId, int tenantId, int locationId) async {
    final cacheKey = '${categoryId}_${tenantId}_$locationId'; // ✅ Include locationId in cache key

    // 1️⃣ Use cache if available
    if (_cache.containsKey(cacheKey)) {
      productResponse.value = _cache[cacheKey];
      return;
    }

    isLoading.value = true;

    bool connected = await hasInternet();
    if (!connected) {
      isLoading.value = false;
      isConnected = false.obs;
      return; // Stop fetching
    }

    // 2️⃣ Otherwise fetch from API
    try {
      isLoading.value = true;

      final response = await provider.getProductsBySubCategory(
        categoryId: categoryId,
        tenantId: tenantId,
        locationId: locationId, // ✅ Pass locationId to API
      );

      productResponse.value = response;

      // 3️⃣ Save in cache
      _cache[cacheKey] = response!;
    } finally {
      isLoading.value = false;
    }
  }

  /// Force refresh API and update cache
  Future<void> refreshProducts(int categoryId, int tenantId, int locationId) async {
    final cacheKey = '${categoryId}_${tenantId}_$locationId'; // ✅ Include locationId

    try {
      isLoading.value = true;

      final response = await provider.getProductsBySubCategory(
        categoryId: categoryId,
        tenantId: tenantId,
        locationId: locationId, // ✅ Pass locationId to API
      );

      productResponse.value = response;

      // ✅ Update cache with new key
      _cache[cacheKey] = response!;
    } finally {
      isLoading.value = false;
    }
  }

  /// Returns products depending on search query and selected subcategory
  List<Product> get filteredProducts {
    // Check if nested data exists (main API)
    final details = productResponse.value?.data?.details;
    if (details != null && details.isNotEmpty) {
      if (searchQuery.value.isEmpty) {
        final selectedDetail = details[selectedIndex.value];
        return selectedDetail.products ?? [];
      }

      List<Product> allProducts = [];
      for (var detail in details) {
        allProducts.addAll(detail.products ?? []);
      }
      return allProducts
          .where((p) =>
          (p.productname ?? '')
              .toLowerCase()
              .contains(searchQuery.value.toLowerCase()))
          .toList();
    }

    // If flat details exist (variants API)
    final variantDetails = productResponse.value?.details ?? [];
    if (variantDetails.isNotEmpty) {
      if (searchQuery.value.isEmpty) return variantDetails;

      return variantDetails
          .where((p) =>
          (p.productname ?? '')
              .toLowerCase()
              .contains(searchQuery.value.toLowerCase()))
          .toList();
    }

    return [];
  }
  // NEW: Dedicated method for subcategory-specific screen
  List<Product> getProductsBySubcategory(String subCategoryName) {
    final details = productResponse.value?.data?.details ?? [];

    if (details.isEmpty) {
      return [];
    }

    // Find matching subcategory (case-insensitive, trimmed for safety)
    final matchingDetail = details.firstWhere(
          (detail) =>
      (detail.subcategoryname ?? '').trim().toLowerCase() ==
          subCategoryName.trim().toLowerCase(),
      orElse: () => Detail(), // fallback - make sure Detail() is valid in your modules
    );

    // Return the products of that subcategory (or empty if no match)
    return matchingDetail.products ?? [];
  }
}
