import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:niogu_app/core/providers/app_provider.dart';
import 'package:niogu_app/features/goods/products/data/repositories/product_repository_impl.dart';
import 'package:niogu_app/features/goods/products/domain/entities/product.dart';
import 'package:niogu_app/features/goods/products/domain/repositories/i_product_repository.dart';
import 'package:niogu_app/features/goods/products/presentation/controllers/product_controller.dart';

final productRepositoryProvider = Provider<IProductRepository>((ref) {
  final _appDatabase = ref.watch(appDatabaseProvider);
  return ProductRepositoryImpl(_appDatabase);
});

final productStreamProvider = StreamProvider.autoDispose<List<Product>>((ref) {
  final productRepository = ref.watch(productRepositoryProvider);

  final currentOutletId = ref.watch(currentOutletIdProvider);

  if(currentOutletId == null) {
    return Stream<List<Product>>.value([]);
  }

  return productRepository.watchProducts(currentOutletId);
});

final productSearchProvider = StateProvider.autoDispose<String>((ref) => '');

final filteredProductProvider = Provider.autoDispose<AsyncValue<List<Product>>>(
  (ref) {
    final productStreamAsync = ref.watch(productStreamProvider);
    final productSearchAsync = ref.watch(productSearchProvider);
    return productStreamAsync.when(
      data: (products) {
        if (productSearchAsync.trim().isEmpty) {
          return AsyncValue.data(products);
        }

        final filteredProducts = products.where((product) {
          return product.name.toLowerCase().contains(
            productSearchAsync.toLowerCase(),
          );
        }).toList();

        return AsyncValue.data(filteredProducts);
      },
      error: (error, stackTrace) {
        return AsyncValue.error(error, stackTrace);
      },
      loading: () => const AsyncValue.loading(),
    );
  },
);

final productEmptyProvider = Provider.autoDispose<ProductEmpty>((ref) {
  final productStreamAsync = ref.watch(productStreamProvider);
  final filteredProductAsync = ref.watch(filteredProductProvider);
  final productSearchAsync = ref.watch(productSearchProvider);

  if (productStreamAsync.isLoading) {
    return ProductEmpty.loading;
  }

  final allProducts = productStreamAsync.value ?? [];

  if (allProducts.isEmpty) {
    return ProductEmpty.empty_database;
  }

  final filteredProduct = filteredProductAsync.value ?? [];

  if (productSearchAsync.isNotEmpty && filteredProduct.isEmpty) {
    return ProductEmpty.empty_search_result;
  }

  return ProductEmpty.has_data;
});

final productControllerProvider =
    AsyncNotifierProvider.autoDispose<ProductController, void>(
      ProductController.new,
    );

final productWithVariantProvider =
    StateProvider.autoDispose<List<ProductWithVariant>>((ref) {
      return [];
    });

final deleteProductVariantProvider = StateProvider<List<DeleteProductVariant>>((
  ref,
) {
  return [];
});

final variantImageTempProvider = StateProvider<List<String?>>((ref) {
  return [];
});

final productChoiceStreamProvider =
    StreamProvider.autoDispose<List<ProductChoice>>((ref) {
      final productRepository = ref.watch(productRepositoryProvider);
      return productRepository.watchProductChoices();
    });

final productChoiceSearchProvider = StateProvider.autoDispose<String>(
  (ref) => '',
);

final filteredProductChoiceProvider =
    Provider.autoDispose<AsyncValue<List<ProductChoice>>>((ref) {
      final productStreamAsync = ref.watch(productChoiceStreamProvider);
      final productSearchAsync = ref.watch(productChoiceSearchProvider);
      return productStreamAsync.when(
        data: (products) {
          if (productSearchAsync.trim().isEmpty) {
            return AsyncValue.data(products);
          }

          final filteredProducts = products.where((product) {
            return product.name.toLowerCase().contains(
              productSearchAsync.toLowerCase(),
            );
          }).toList();

          return AsyncValue.data(filteredProducts);
        },
        error: (error, stackTrace) {
          return AsyncValue.error(error, stackTrace);
        },
        loading: () => const AsyncValue.loading(),
      );
    });

final productChoiceEmptyProvider = Provider.autoDispose<ProductChoiceEmpty>((
  ref,
) {
  final productStreamAsync = ref.watch(productChoiceStreamProvider);
  final filteredProductAsync = ref.watch(filteredProductChoiceProvider);
  final productSearchAsync = ref.watch(productChoiceSearchProvider);

  if (productStreamAsync.isLoading) {
    return ProductChoiceEmpty.loading;
  }

  final allProducts = productStreamAsync.value ?? [];

  if (allProducts.isEmpty) {
    return ProductChoiceEmpty.empty_database;
  }

  final filteredProduct = filteredProductAsync.value ?? [];

  if (productSearchAsync.isNotEmpty && filteredProduct.isEmpty) {
    return ProductChoiceEmpty.empty_search_result;
  }

  return ProductChoiceEmpty.has_data;
});

final selectedNewVariantProvider = StateProvider.autoDispose<Map<String, bool>>(
  (ref) => {},
);
