import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:niogu_ecommerce_v1/core/enums/order_status.dart';
import 'package:niogu_ecommerce_v1/core/providers/app_provider.dart';
import 'package:niogu_ecommerce_v1/features/order/data/datasource/order_remote_datasource_impl.dart';
import 'package:niogu_ecommerce_v1/features/order/data/repositories/order_repository_impl.dart';
import 'package:niogu_ecommerce_v1/features/order/domain/entities/order.dart';
import 'package:niogu_ecommerce_v1/features/order/domain/repositories/i_order_repository.dart';
import 'package:niogu_ecommerce_v1/features/order/presentation/controllers/order_controller.dart';

final orderRemoteDatasourceProvider =
    Provider.autoDispose<IOrderRemoteDatasource>((ref) {
      final dio = ref.watch(dioProvider);

      return OrderRemoteDatasourceImpl(dio);
    });

final orderRepositoryProvider = Provider.autoDispose<IOrderRepository>((ref) {
  final orderRemoteDatasource = ref.watch(orderRemoteDatasourceProvider);

  return OrderRepositoryImpl(orderRemoteDatasource);
});

final orderReportControllerProvider =
    AsyncNotifierProvider.autoDispose<OrderReportController, List<OrderReport>>(
      OrderReportController.new,
    );

final orderControllerProvider =
    AsyncNotifierProvider.autoDispose<OrderController, void>(
      OrderController.new,
    );

final orderProvider = Provider.family
    .autoDispose<AsyncValue<List<OrderReport>>, List<OrderStatus>>((
      ref,
      orderStatuses,
    ) {
      final isLoggedIn = ref.watch(currentStatusLoginProvider);

      if (!isLoggedIn) return AsyncValue.data([]);

      final orderState = ref.watch(orderReportControllerProvider);

      return orderState.when(
        data: (orders) {
          if (orders.isEmpty) return AsyncValue.data([]);

          final filteredOrders = orders
              .where((order) => orderStatuses.contains(order.orderStatus))
              .toList();

          return AsyncValue.data(filteredOrders);
        },
        error: (error, st) => AsyncValue.error(error, st),
        loading: () => const AsyncValue.loading(),
      );
    });
