import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:niogu_app/core/providers/app_provider.dart';
import 'package:niogu_app/features/customer/data/repositories/customer_repository_impl.dart';
import 'package:niogu_app/features/customer/domain/entities/customer.dart';
import 'package:niogu_app/features/customer/domain/repositories/i_customer_repository.dart';
import 'package:niogu_app/features/customer/presentation/controllers/customer_controller.dart';

final customerRepositoryProvider = Provider<ICustomerRepository>((ref) {
  final appDatabase = ref.watch(appDatabaseProvider);
  return CustomerRepositoryImpl(appDatabase);
});

final customerStreamProvider =
    StreamProvider.autoDispose<List<DisplayCustomers>>((ref) {
      final customerRepository = ref.watch(customerRepositoryProvider);
      return customerRepository.watchCustomers();
    });

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

final filteredCustomerProvider =
    Provider.autoDispose<AsyncValue<List<DisplayCustomers>>>((ref) {
      final customerStreamAsync = ref.watch(customerStreamProvider);
      final customerSearchAsync = ref.watch(customerSearchProvider);
      return customerStreamAsync.when(
        data: (customers) {
          if (customerSearchAsync.trim().isEmpty) {
            return AsyncValue.data(customers);
          }

          final filteredCustomers = customers.where((customer) {
            return customer.name.toLowerCase().contains(
              customerSearchAsync.toLowerCase(),
            );
          }).toList();

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

final customerEmptyProvider = Provider.autoDispose<CustomerEmpty>((ref) {
  final customerStreamAsync = ref.watch(customerStreamProvider);
  final filteredCustomerAsync = ref.watch(filteredCustomerProvider);
  final customerSearchAsync = ref.watch(customerSearchProvider);

  if (customerStreamAsync.isLoading) {
    return CustomerEmpty.loading;
  }

  final allCustomers = customerStreamAsync.value ?? [];

  if (allCustomers.isEmpty) {
    return CustomerEmpty.empty_database;
  }

  final filteredCustomers = filteredCustomerAsync.value ?? [];

  if (customerSearchAsync.isNotEmpty && filteredCustomers.isEmpty) {
    return CustomerEmpty.empty_search_result;
  }

  return CustomerEmpty.has_data;
});

final customerAddressesProvider = StreamProvider.family
    .autoDispose<List<CustomerAddress>, String>((ref, customerId) {
      final customerRepository = ref.watch(customerRepositoryProvider);
      return customerRepository.watchCustomerAddresses(customerId);
    });

final customerActivitiesProvider = StreamProvider.family
    .autoDispose<List<CustomerActivities>, String>((ref, customerId) {
      final customerRepository = ref.watch(customerRepositoryProvider);
      return customerRepository.watchCustomerActivities(customerId);
    });

final customerControllerProvider =
    AsyncNotifierProvider.autoDispose<CustomerController, void>(
      CustomerController.new,
    );
