import 'package:concierge/data/local/secure_storage/concierge_secure_storage.dart';
import 'package:concierge/data/remote/models/product.dart';
import 'package:concierge/domain/models/app_error.dart';
import 'package:concierge/domain/models/data_state.dart';
import 'package:concierge/domain/repositories/property_repository.dart';
import 'package:concierge/presentation/base/base_cubit.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part '../../_generated/presentation/app/concierge_cubit.freezed.dart';

class ConciergeCubit extends BaseCubit<ConciergeState> {
  final PropertyRepository _propertyRepository;
  final Map<String, String> launchParameters;

  ConciergeCubit(
    this._propertyRepository,{
    required this.launchParameters,
  }) : super(const ConciergeState());

  String get roomNumber => launchParameters["room-number"] ?? "";

  DataState getProductState(int pId) {
    final pExists = state.products.containsKey(pId);
    if (!pExists) {
      _loadProduct(pId);
      return DataState.loading;
    }
    return state.products[pId]!;
  }

  Future<void> _loadProduct(int pId) async {
    if (state.products.containsKey(pId)) {
      if (state.products[pId] == DataState.loading) return;
      if (state.products[pId] is Success<Product>) return;
    }
    try {
      _updateProductDataState(pId, DataState.loading);
      final product = await _propertyRepository.getProduct(pId);
      _updateProductDataState(pId, DataState.success(product));
    } catch (e, st) {
      handleError(e, st);
      _updateProductDataState(pId, DataState.failure(AppError.unknown(e.toString())));
    }
  }

  void _updateProductDataState(int pId, DataState dataState) {
    final copy = Map.of(state.products);
    copy[pId] = dataState;
    safeEmit(state.copyWith(products: copy));
  }

  @override
  Future<void> close() async {
    return super.close();
  }
}

@freezed
abstract class ConciergeState with _$ConciergeState {
  const factory ConciergeState({
    @Default({}) Map<int, DataState> products,
    @Default("") String roomNumber,
  }) = _ConciergeState;
}