import 'dart:async';

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:laki_icu_app/models/bo/bluetooth_read_model.dart';
import 'package:laki_icu_app/utils/event_bus.dart';
import 'package:laki_icu_app/utils/logger.dart';
import 'package:laki_icu_app/utils/storage/storage_service.dart';

import 'bluetooth_read_event.dart';
import 'bluetooth_read_state.dart';

class BluetoothReadBloc extends Bloc<BluetoothReadEvent, BluetoothReadState> {
  final StorageService _storageService;
  late final StreamSubscription<BluetoothReadInfoChangedEvent> _infoChangedSub;
  late final StreamSubscription<BluetoothReadInfoClearedEvent> _infoClearedSub;

  BluetoothReadBloc({
    required StorageService storageService,
  })  : _storageService = storageService,
        super(const BluetoothReadState()) {
    on<BluetoothReadLoadRequested>(_onLoadRequested);
    on<BluetoothReadUpdated>(_onUpdated);
    on<BluetoothReadCleared>(_onCleared);

    _infoChangedSub = eventBus.on<BluetoothReadInfoChangedEvent>().listen(
          (event) => add(BluetoothReadUpdated(event.info)),
        );
    _infoClearedSub = eventBus.on<BluetoothReadInfoClearedEvent>().listen(
          (_) => add(const BluetoothReadCleared()),
        );

    add(const BluetoothReadLoadRequested());
  }

  Future<void> _onLoadRequested(
    BluetoothReadLoadRequested event,
    Emitter<BluetoothReadState> emit,
  ) async {
    emit(state.copyWith(isLoading: true, clearError: true));
    try {
      BluetoothReadModel? info;
      const maxRetries = 5;
      const retryInterval = Duration(seconds: 10);

      for (int i = 0; i < maxRetries; i++) {
        try {
          info = await _storageService.getBluetoothReadInfo();
          Log.warn(
              '**************sn 第${i + 1}次获取************: ${info.sn}');
          if (info.hasSn) {
            Log.warn('**************sn 获取成功，停止重试************');
            break;
          }
        } catch (e) {
          Log.warn('**************sn 第${i + 1}次获取失败: $e************');
        }

        // 如果还没获取到sn且不是最后一次，则等待后重试
        if (i < maxRetries - 1 && (info == null || !info.hasSn)) {
          await Future.delayed(retryInterval);
        }
      }

      emit(state.copyWith(
        info: info ?? BluetoothReadModel.empty,
        isLoading: false,
        clearError: true,
      ));
    } catch (e) {
      emit(state.copyWith(isLoading: false, error: e.toString()));
    }
  }

  void _onUpdated(
    BluetoothReadUpdated event,
    Emitter<BluetoothReadState> emit,
  ) {
    emit(state.copyWith(info: event.info, clearError: true));
  }

  void _onCleared(
    BluetoothReadCleared event,
    Emitter<BluetoothReadState> emit,
  ) {
    emit(state.copyWith(info: BluetoothReadModel.empty, clearError: true));
  }

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