import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flux/core/blocs/session/session_cubit.dart';
import 'package:flux/features/master_data/providers/models/provider_model.dart';
import 'package:flux/features/master_data/staff/data/staff_repository.dart';
import 'package:flux/features/master_data/staff/models/staff_member_model.dart';
import 'package:flux/features/master_data/store/data/store_repository.dart';
import 'package:flux/features/master_data/store/models/store_model.dart';
import 'package:get_it/get_it.dart';

part 'store_state.dart';

class StoreCubit extends Cubit<StoreState> {
  final StoreRepository _repository = GetIt.I<StoreRepository>();
  final StaffRepository _staffRepository = GetIt.I<StaffRepository>();
  final SessionCubit _sessionCubit = GetIt.I<SessionCubit>();

  StoreCubit() : super(const StoreState(stores: []));

  Future<void> saveStore(final StoreModel store) async {
    emit(state.copyWith(status: StoreStatus.loading));
    try {
      final savedStore = await _repository.saveStore(store);
      emit(state.copyWith(status: StoreStatus.success, savedStore: savedStore));
    } catch (e) {
      emit(
        state.copyWith(
          status: StoreStatus.failure,
          errorMessage: e.toString(),
          savedStore: null,
        ),
      );
    }
  }

  Future<void> loadStores() async {
    emit(state.copyWith(status: StoreStatus.loading));
    try {
      final stores = await _repository.fetchAllCompanyStores(
        _sessionCubit.state.company!.id!,
      );
      final Map<String, List<StaffMemberModel>> staffByStore = {};
      for (StoreModel store in stores) {
        staffByStore[store.id!] = await _staffRepository.getStaffMembersInStore(
          store.id!,
        );
      }
      emit(
        state.copyWith(
          status: StoreStatus.success,
          stores: stores,
          staffByStore: staffByStore,
        ),
      );
    } catch (e) {
      emit(
        state.copyWith(status: StoreStatus.failure, errorMessage: e.toString()),
      );
    }
  }

  Future<void> saveProvidersForStore(
    StoreModel store,
    List<ProviderModel> providers,
  ) async {
    emit(state.copyWith(status: StoreStatus.loading));

    try {
      final savedStore = await _repository.saveStore(store);
      await _repository.syncStoreProviders(savedStore.id!, providers);
      await loadStores();
    } catch (e) {
      emit(
        state.copyWith(
          status: StoreStatus.failure,
          errorMessage: "Errore nel salvataggio dei provider: $e",
          savedStore: null,
        ),
      );
    }
  }

  Future<void> saveStaffForStore(
    StoreModel store,
    List<StaffMemberModel> staffMembers,
  ) async {
    emit(state.copyWith(status: StoreStatus.loading));

    try {
      final savedStore = await _repository.saveStore(store);
      await _repository.syncStoreStaff(savedStore.id!, staffMembers);
      await loadStores();
    } catch (e) {
      emit(
        state.copyWith(
          status: StoreStatus.failure,
          errorMessage: "Errore nel salvataggio dello staff: $e",
          savedStore: null,
        ),
      );
    }
  }

  Future<void> associateStoreToProvider(
    String storeId,
    String providerId,
  ) async {
    try {
      await _repository.associateStoreToProvider(
        providerId: providerId,
        storeId: storeId,
      );
      loadStores();
    } catch (e) {
      emit(
        state.copyWith(
          status: StoreStatus.failure,
          errorMessage: "Errore nell'associazione: $e",
          savedStore: null,
        ),
      );
    }
  }

  Future<void> removeProviderFromStore(
    String storeId,
    String providerId,
  ) async {
    try {
      await _repository.removeStoreFromProvider(
        providerId: providerId,
        storeId: storeId,
      );
      loadStores();
    } catch (e) {
      emit(
        state.copyWith(
          status: StoreStatus.failure,
          errorMessage: "Errore nella rimozione: $e",
          savedStore: null,
        ),
      );
    }
  }

  Future<void> assignStaffToStore(String storeId, String staffId) async {
    try {
      await _staffRepository.assignStaffToStore(staffId, storeId);
      // Dopo l'assegnazione, potresti voler ricaricare lo staff per quel negozio
      loadStores();
    } catch (e) {
      emit(
        state.copyWith(
          status: StoreStatus.failure,
          errorMessage: e.toString(),
          savedStore: null,
        ),
      );
    }
  }

  // Rimuove un dipendente da un negozio
  Future<void> removeStaffFromStore(String staffId, String storeId) async {
    try {
      await _staffRepository.removeStaffFromStore(staffId, storeId);
      loadStores();
    } catch (e) {
      emit(
        state.copyWith(
          status: StoreStatus.failure,
          errorMessage: "Errore nella rimozione: $e",
          savedStore: null,
        ),
      );
    }
  }
}
