import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:niogu_app/core/providers/app_provider.dart';
import 'package:niogu_app/core/enums/item_type.dart';
import 'package:niogu_app/core/enums/report_type.dart';
import 'package:niogu_app/features/report/presentation/providers/report_provider.dart';
import 'package:niogu_app/features/report/stock_report/data/repositories/stock_report_repository_impl.dart';
import 'package:niogu_app/features/report/stock_report/domain/entities/stok_report.dart';
import 'package:niogu_app/features/report/stock_report/domain/repositories/i_stock_report_repository.dart';

final stockReportRepositoryProvider =
    Provider.autoDispose<IStockReportRepository>((ref) {
      final appDatabase = ref.watch(appDatabaseProvider);
      return StockReportRepositoryImpl(appDatabase);
    });

final filteredByItemTypeProvider = StateProvider.autoDispose<ItemType?>(
  (ref) => null,
);

final stockReportStreamProvider =
    StreamProvider.autoDispose<List<StockReportItem>>((ref) {
      final isLoggedIn = ref.watch(currentStatusLoginProvider);

      final stockReportRepository = ref.watch(stockReportRepositoryProvider);

      final outletId = ref.watch(
        filteredByOutletProvider(ReportType.stock_card),
      );

      final itemType = ref.watch(filteredByItemTypeProvider);

      final date = ref.watch(filteredByDateTimeProvider(ReportType.stock_card));

      final startDate = date?.start;

      final endDate = date?.end;

      if (!isLoggedIn) {
        return Stream<List<StockReportItem>>.value([]);
      }

      return stockReportRepository.watchStockReports(
        outletId: outletId,
        itemType: itemType,
        startDate: startDate,
        endDate: endDate,
      );
    });

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

final filteredStockReportProvider =
    Provider.autoDispose<AsyncValue<List<StockReportItem>>>((ref) {
      final stockReportStreamAsync = ref.watch(stockReportStreamProvider);
      final stockReportSearchAsync = ref.watch(stockReportSearchProvider);
      return stockReportStreamAsync.when(
        data: (stockReports) {
          if (stockReportSearchAsync.trim().isEmpty) {
            return AsyncValue.data(stockReports);
          }

          final filteredStockReport = stockReports.where((stockReport) {
            return stockReport.name.toLowerCase().contains(
              stockReportSearchAsync.toLowerCase(),
            );
          }).toList();

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

final stockReportEmptyProvider = Provider.autoDispose<StockReportItemEmpty>((
  ref,
) {
  final stockReportStreamAsync = ref.watch(stockReportStreamProvider);
  final filteredStockReportAsync = ref.watch(filteredStockReportProvider);
  final stockReportSearchAsync = ref.watch(stockReportSearchProvider);

  if (stockReportStreamAsync.isLoading) {
    return StockReportItemEmpty.loading;
  }

  final allStockReprts = stockReportStreamAsync.value ?? [];

  if (allStockReprts.isEmpty) {
    return StockReportItemEmpty.empty_database;
  }

  final filteredStockReports = filteredStockReportAsync.value ?? [];

  if (stockReportSearchAsync.isNotEmpty && filteredStockReports.isEmpty) {
    return StockReportItemEmpty.empty_search_result;
  }

  return StockReportItemEmpty.has_data;
});
