import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:niogu_app/features/goods/domain/entities/stock_card.dart';
import 'package:niogu_app/features/goods/raw_materials/domain/entities/raw_material.dart';
import 'package:niogu_app/features/goods/raw_materials/domain/repositories/i_raw_material_repository.dart';
import 'package:niogu_app/features/goods/raw_materials/presentation/providers/raw_material_provider.dart';
import 'package:niogu_app/features/goods/domain/entities/outlet_inventory.dart';

class RawMaterialController extends AutoDisposeAsyncNotifier<void> {
  late final IRawMaterialRepository _rawMaterialRepository;
  @override
  FutureOr<void> build() {
    _rawMaterialRepository = ref.read(rawMaterialRepositoryProvider);
  }

  Future<void> saveRawMaterial({
    required UpsertRawMaterial rawMaterial,
    required List<UpsertReceiptItem> receiptItems,
    List<DeleteProductUsageMaterial>? deleteItems,
    required List<UpsertOutletInventory> outletInventories,
    required List<StockCard> stockCards,
  }) async {
    state = const AsyncValue.loading();

    final result = await AsyncValue.guard(() async {
      await _rawMaterialRepository.saveRawMaterial(
        rawMaterial: rawMaterial,
        receiptItems: receiptItems,
        deleteItems: deleteItems,
        outletInventories: outletInventories,
        stockCards: stockCards,
      );
    });

    state = result;

    if (result is AsyncError) throw result.error!;
  }

  Future<void> deleteRawMaterial(
    String id, {
    String? outletId,
    bool canDeleteAll = false,
  }) async {
    state = const AsyncValue.loading();

    final result = await AsyncValue.guard(() async {
      await _rawMaterialRepository.deleteRawMaterial(
        id,
        outletId: outletId,
        canDeleteAll: canDeleteAll,
      );
    });

    state = result;

    if (result is AsyncError) throw result.error!;
  }
}

class SelectedProductUsageMaterialController
    extends StateNotifier<Map<String, SelectedProductUsageMaterial>> {
  SelectedProductUsageMaterialController() : super({});

  double quantityOf(String productUsageId) =>
      state[productUsageId]?.quantity ?? 0.0;

  void hydrate(List<SelectedProductUsageMaterial> oldData) {
    state = {for (final data in oldData) data.productUsageId: data};
  }

  void restore(Map<String, SelectedProductUsageMaterial> initialProductUsages) {
    state = Map.from(initialProductUsages);
  }

  void toggle(String productUsageId, String? receiptItemId) {
    if (state.containsKey(productUsageId)) {
      state = {...state}..remove(productUsageId);
    } else {
      state = {
        ...state,
        productUsageId: SelectedProductUsageMaterial(
          receiptItemId: receiptItemId,
          productUsageId: productUsageId,
          quantity: 0.0,
        ),
      };
    }
  }

  void setQuantity(String productUsageId, double quantity) {
    if (!state.containsKey(productUsageId)) return;

    state = {
      ...state,
      productUsageId: state[productUsageId]!.copyWith(quantity: quantity),
    };
  }

  void clear() => state = {};
}
