import 'dart:async';

import 'package:comwell_key_app/base/base_cubit.dart';
import 'package:comwell_key_app/domain/repositories/bluetooth_repository.dart';
import 'package:comwell_key_app/domain/repositories/internet_status_repository.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part '../.generated/connection_state/connection_state_cubit.freezed.dart';

class ConnectionStateCubit extends BaseCubit<AppConnectionState> {
  ConnectionStateCubit(this._bluetoothRepository, this._internetStatusRepository)
    : super(const AppConnectionState()) {
    _init();
  }

  final BluetoothRepository _bluetoothRepository;
  final InternetStatusRepository _internetStatusRepository;
  late final StreamSubscription<bool> _internetStatusSubscription;
  late final StreamSubscription<bool> _bluetoothStatusSubscription;

  Future<void> _init() async {
    try {
      _internetStatusSubscription = _internetStatusRepository.isConnectedStream().listen((value) {
        safeEmit(state.copyWith(isInternetConnected: value));
      });
      _bluetoothStatusSubscription = _bluetoothRepository.isEnabledStream().listen((value) {
        safeEmit(state.copyWith(isBluetoothEnabled: value));
      });
      safeEmit(state.copyWith(isLoading: true));
      await Future.wait([_checkBluetooth(), _checkInternet()]);
    } catch (e, st) {
      logError(e, st);
    } finally {
      safeEmit(state.copyWith(isLoading: false));
    }
  }

  Future<void> _checkBluetooth() async {
    final isSupported = await _bluetoothRepository.isSupported();
    final isEnabled = await _bluetoothRepository.isEnabled();
    final isPermissionGranted = await _bluetoothRepository.isPermissionGranted();
    safeEmit(
      state.copyWith(
        isBluetoothSupported: isSupported,
        isBluetoothEnabled: isEnabled,
        isBluetoothPermissionGranted: isPermissionGranted,
      ),
    );
  }

  Future<void> _checkInternet() async {
    final isConnected = await _internetStatusRepository.isConnected();
    safeEmit(state.copyWith(isInternetConnected: isConnected));
  }

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

@freezed
abstract class AppConnectionState with _$AppConnectionState {
  const factory AppConnectionState({
    @Default(false) bool isLoading,
    @Default(true) bool isBluetoothEnabled,
    @Default(true) bool isInternetConnected,
    @Default(true) bool isBluetoothSupported,
    @Default(true) bool isBluetoothPermissionGranted,
  }) = _AppConnectionState;
}