import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import '../../../domain/entities/logistic_object.dart';
import '../../../domain/entities/tour.dart';
import '../../../domain/repositories/tour_repository.dart';
import '../../../core/constants/app_constants.dart';
import '../../../core/errors/failures.dart';

part 'scan_event.dart';
part 'scan_state.dart';

class ScanBloc extends Bloc<ScanEvent, ScanState> {
  final TourRepository repository;
  Tour? currentTour;
  String? currentPageId;
  String? scannedFsaId;
  
  // Container handling for VS state machine
  String? containerId;
  String? containerType; // 'a' or 'b'

  ScanBloc({required this.repository}) : super(ScanInitial()) {
    on<InitializeScan>(_onInitializeScan);
    on<ProcessBarcode>(_onProcessBarcode);
    on<ValidateBarcode>(_onValidateBarcode);
    on<UpdateObjectState>(_onUpdateObjectState);
    on<ResetScan>(_onResetScan);
    on<CreateUnknownObject>(_onCreateUnknownObject);
  }

  Future<void> _onInitializeScan(InitializeScan event, Emitter<ScanState> emit) async {
    currentTour = event.tour;
    containerId = null;
    containerType = null;
    emit(ScanReady(tour: event.tour));
  }

  Future<void> _onProcessBarcode(ProcessBarcode event, Emitter<ScanState> emit) async {
    emit(ScanProcessing(barcode: event.barcode));

    final barcode = event.barcode.trim();
    
    // Prüfe auf spezielle Barcodes (Seiten-Codes)
    if (currentTour != null) {
      final pageInfo = _findPageForBarcode(barcode);
      if (pageInfo != null) {
        emit(ScanPageDetected(
          pageId: pageInfo['pageId']!,
          label: pageInfo['label']!,
          tour: currentTour!,
        ));
        return;
      }
    }

    // Suche Objekt nach Barcode
    final result = await repository.getObjectByBarcode(barcode);
    
    result.fold(
      (failure) => emit(ScanError(message: _mapFailureToMessage(failure))),
      (object) {
        if (object != null) {
          _processScannedObject(object, barcode, emit);
        } else {
          // Unbekanntes Objekt - prüfe auf gültiges Präfix
          final prefix = barcode.length >= 3 ? barcode.substring(0, 3) : '';
          if (_isValidPrefix(prefix)) {
            emit(ScanUnknownObject(
              barcode: barcode,
              prefix: prefix,
              tour: currentTour,
            ));
          } else {
            emit(ScanError(message: 'Unbekannter Barcode: $barcode'));
          }
        }
      },
    );
  }

  void _processScannedObject(LogisticObject object, String barcode, Emitter<ScanState> emit) {
    if (currentTour == null) {
      emit(const ScanError(message: 'Keine Tour ausgewählt'));
      return;
    }

    final tourType = currentTour!.type;
    
    // Dispatch to appropriate state machine based on tour type
    switch (tourType) {
      case TourTypes.stockStart:
        _stockStartStateMachine(object, emit);
        break;
      case TourTypes.vehStart:
        _vehStartStateMachine(object, emit);
        break;
      case TourTypes.vehBulk:
        _vehBulkStateMachine(object, emit);
        break;
      case TourTypes.veh:
        _vehStateMachine(object, emit);
        break;
      case TourTypes.fsa:
        _fsaStateMachine(object, emit);
        break;
      case TourTypes.vs:
        _vsStateMachine(object, emit);
        break;
      case TourTypes.vehVs:
        _vehVsStateMachine(object, emit);
        break;
      case TourTypes.gi:
        _giStateMachine(object, emit);
        break;
      case TourTypes.vehEnd:
        _vehEndStateMachine(object, emit);
        break;
      case TourTypes.stockEnd:
        _stockEndStateMachine(object, emit);
        break;
      case TourTypes.stock:
        _stockStateMachine(object, emit);
        break;
      default:
        // Fallback to simple state machine for unknown tour types
        final nextState = _determineNextState(object);
        emit(ScanObjectDetected(
          object: object,
          suggestedState: nextState,
          tour: currentTour,
        ));
    }
  }

  // ============================================================================
  // STATE MACHINE: stockStart (Lager Beladung)
  // ============================================================================
  void _stockStartStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final currentState = object.state;
    
    if (currentState == ObjectStates.unknown) {
      emit(ScanObjectDetected(
        object: object,
        suggestedState: ObjectStates.toDelivery,
        tour: currentTour,
      ));
    } else if (currentState == ObjectStates.finGITmp) {
      emit(ScanObjectDetected(
        object: object,
        suggestedState: ObjectStates.retGI,
        tour: currentTour,
      ));
    } else {
      emit(const ScanError(
        message: 'Fehler: Ungültiger Barcode für Lager Beladung',
      ));
    }
  }

  // ============================================================================
  // STATE MACHINE: vehStart (Fahrzeug Start)
  // ============================================================================
  void _vehStartStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final currentState = object.state;
    
    if (currentState == ObjectStates.toDelivery) {
      emit(ScanObjectDetected(
        object: object,
        suggestedState: ObjectStates.delivery,
        tour: currentTour,
      ));
    } else if (currentState == ObjectStates.retGI) {
      emit(ScanObjectDetected(
        object: object,
        suggestedState: ObjectStates.retGIFzg,
        tour: currentTour,
      ));
    } else {
      emit(const ScanError(message: 'Fehler: Ungültiger Barcode'));
    }
  }

  // ============================================================================
  // STATE MACHINE: vehBulk (Fahrzeug Bulk)
  // ============================================================================
  void _vehBulkStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final objectType = object.type;
    final currentState = object.state;
    
    // Type 9 = special bulk handling
    if (objectType == 9) {
      // Bulk update all objects with state to_delivery
      emit(ScanObjectDetected(
        object: object,
        suggestedState: ObjectStates.delivery,
        tour: currentTour,
      ));
    } else {
      if (currentState == ObjectStates.toDelivery) {
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.delivery,
          tour: currentTour,
        ));
      } else if (currentState == ObjectStates.retGI) {
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retGIFzg,
          tour: currentTour,
        ));
      } else {
        emit(const ScanError(message: 'Fehler: Ungültiger Barcode'));
      }
    }
  }

  // ============================================================================
  // STATE MACHINE: veh (Fahrzeug - Stationen)
  // ============================================================================
  void _vehStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final currentState = object.state;
    
    switch (currentState) {
      case ObjectStates.delivery:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.station,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retFail:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retFailFzg,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retGI:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retGIFzg,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retDS:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDSFzg,
          tour: currentTour,
        ));
        break;
      case ObjectStates.station:
        // Reverse transition: back to delivery
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.delivery,
          tour: currentTour,
        ));
        break;
      case ObjectStates.inFA:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.hdl,
          tour: currentTour,
        ));
        break;
      default:
        emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  // ============================================================================
  // STATE MACHINE: fsa (Fahrscheinautomat)
  // ============================================================================
  void _fsaStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final objectType = object.type;
    final currentState = object.state;
    final subtype = object.subtype.toLowerCase();
    
    // GK = Geldkassette (type 1)
    if (_isTypeGK(objectType, subtype)) {
      _fsaGKStateMachine(object, currentState, emit);
    }
    // HP = Hauptkasse/Druckerpatronen (type 2)
    else if (_isTypeHP(objectType, subtype)) {
      _fsaHPStateMachine(object, currentState, emit);
    }
    // FR = Fahrkartenrolle (type 5)
    else if (_isTypeFR(objectType, subtype)) {
      _fsaFRStateMachine(object, currentState, emit);
    }
    else {
      emit(const ScanError(message: 'Fehler: Falscher Typ für FSA'));
    }
  }

  void _fsaGKStateMachine(LogisticObject object, String currentState, Emitter<ScanState> emit) {
    switch (currentState) {
      case ObjectStates.station:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.inFA,
          tour: currentTour,
        ));
        break;
      case ObjectStates.inFA:
        // Special handling: Fehlkassette logic
        emit(ScanFehlKassetteDetected(
          object: object,
          suggestedState: ObjectStates.retFail,
          tour: currentTour,
        ));
        break;
      case ObjectStates.unknown:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retGI,
          tour: currentTour,
          originBarcode: object.code,
        ));
        break;
      default:
        emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  void _fsaHPStateMachine(LogisticObject object, String currentState, Emitter<ScanState> emit) {
    switch (currentState) {
      case ObjectStates.station:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.inFA,
          tour: currentTour,
        ));
        break;
      case ObjectStates.inFA:
        // Bidirectional: back to station
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.station,
          tour: currentTour,
        ));
        break;
      case ObjectStates.unknown:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDS,
          tour: currentTour,
          originBarcode: object.code,
        ));
        break;
      default:
        emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  void _fsaFRStateMachine(LogisticObject object, String currentState, Emitter<ScanState> emit) {
    switch (currentState) {
      case ObjectStates.station:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.inFA,
          tour: currentTour,
        ));
        break;
      case ObjectStates.inFA:
        // Bidirectional: back to station
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.station,
          tour: currentTour,
        ));
        break;
      default:
        emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  // ============================================================================
  // STATE MACHINE: vs (Versorgungsstelle)
  // ============================================================================
  void _vsStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final objectType = object.type;
    final currentState = object.state;
    final subtype = object.subtype.toLowerCase();
    
    // SB = Safebag
    if (_isTypeSB(objectType, subtype)) {
      _vsSBStateMachine(object, currentState, emit);
    }
    // ABS = Abfallbehälter
    else if (_isTypeABS(objectType, subtype)) {
      _vsABSStateMachine(object, currentState, emit);
    }
    // CNTR = Container
    else if (_isTypeCNTR(objectType, subtype)) {
      _vsCNTRStateMachine(object, currentState, subtype, emit);
    }
    else {
      emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  void _vsSBStateMachine(LogisticObject object, String currentState, Emitter<ScanState> emit) {
    if (containerId == null) {
      emit(const ScanError(message: 'Fehler: Falscher Zustand - Container nicht ausgewählt'));
      return;
    }
    
    if (containerType == 'a') {
      if (currentState == ObjectStates.inVS) {
        emit(ScanContainerObjectDetected(
          object: object,
          suggestedState: ObjectStates.retGI,
          tour: currentTour,
          containerId: containerId!,
          containerType: containerType!,
        ));
      } else {
        emit(const ScanError(message: 'Fehler: Falscher Zustand'));
      }
    } else {
      emit(const ScanError(message: 'Fehler: Falscher Zustand'));
    }
  }

  void _vsABSStateMachine(LogisticObject object, String currentState, Emitter<ScanState> emit) {
    if (containerId == null) {
      emit(const ScanError(message: 'Fehler: Falscher Zustand - Container nicht ausgewählt'));
      return;
    }
    
    if (containerType == 'a') {
      emit(const ScanError(message: 'Fehler: Falscher Zustand'));
    } else {
      if (currentState == ObjectStates.inVS) {
        emit(ScanContainerObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDS,
          tour: currentTour,
          containerId: containerId!,
          containerType: containerType!,
        ));
      } else {
        emit(const ScanError(message: 'Fehler: Falscher Zustand'));
      }
    }
  }

  void _vsCNTRStateMachine(LogisticObject object, String currentState, String subtype, Emitter<ScanState> emit) {
    containerId = object.code;
    
    if (subtype == 'cntra') {
      containerType = 'a';
      emit(ScanContainerDetected(
        object: object,
        suggestedState: ObjectStates.retcGI,
        tour: currentTour,
        containerId: containerId!,
        containerType: containerType!,
      ));
    } else if (subtype == 'cntrb') {
      containerType = 'b';
      emit(ScanContainerDetected(
        object: object,
        suggestedState: ObjectStates.retcDS,
        tour: currentTour,
        containerId: containerId!,
        containerType: containerType!,
      ));
    } else {
      emit(const ScanError(message: 'Fehler: Unbekannter Container-Typ'));
    }
  }

  // ============================================================================
  // STATE MACHINE: vehVs (Fahrzeug VS)
  // ============================================================================
  void _vehVsStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final objectType = object.type;
    final currentState = object.state;
    final subtype = object.subtype.toLowerCase();
    
    // SB and ABS not allowed in vehVs
    if (_isTypeSB(objectType, subtype) || _isTypeABS(objectType, subtype)) {
      emit(const ScanError(message: 'Fehler: Falscher Status'));
      return;
    }
    
    // CNTR = Container
    if (_isTypeCNTR(objectType, subtype)) {
      _vehVsCNTRStateMachine(object, currentState, subtype, emit);
    } else {
      emit(const ScanError(message: 'Fehler: Falscher Typ'));
    }
  }

  void _vehVsCNTRStateMachine(LogisticObject object, String currentState, String subtype, Emitter<ScanState> emit) {
    if (subtype == 'cntra') {
      if (currentState == ObjectStates.retcGI) {
        // Update all container objects and clear container
        emit(ScanContainerCloseDetected(
          object: object,
          suggestedState: ObjectStates.unknown,
          targetStateForObjects: ObjectStates.retGIFzg,
          tour: currentTour,
          containerType: 'a',
        ));
        containerId = null;
        containerType = null;
      } else {
        emit(const ScanError(message: 'Fehler: Falscher Status'));
      }
    } else if (subtype == 'cntrb') {
      if (currentState == ObjectStates.retcDS) {
        // Update all container objects and clear container
        emit(ScanContainerCloseDetected(
          object: object,
          suggestedState: ObjectStates.unknown,
          targetStateForObjects: ObjectStates.retDSFzg,
          tour: currentTour,
          containerType: 'b',
        ));
        containerId = null;
        containerType = null;
      } else {
        emit(const ScanError(message: 'Fehler: Falscher Status'));
      }
    }
  }

  // ============================================================================
  // STATE MACHINE: gi (Geldinstitut)
  // ============================================================================
  void _giStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final objectType = object.type;
    final currentState = object.state;
    final subtype = object.subtype.toLowerCase();
    
    // GK = Geldkassette
    if (_isTypeGK(objectType, subtype)) {
      _giGKStateMachine(object, currentState, emit);
    }
    // SB = Safebag
    else if (_isTypeSB(objectType, subtype)) {
      _giSBStateMachine(object, currentState, emit);
    }
    else {
      emit(const ScanError(message: 'Fehler: Falscher Typ'));
    }
  }

  void _giGKStateMachine(LogisticObject object, String currentState, Emitter<ScanState> emit) {
    switch (currentState) {
      case ObjectStates.retGIFzg:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.finGI,
          tour: currentTour,
        ));
        break;
      case ObjectStates.unknown:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDSEmpty,
          tour: currentTour,
        ));
        break;
      case ObjectStates.delivery:
        emit(const ScanError(message: 'Fehler: Falscher Status'));
        break;
      default:
        emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  void _giSBStateMachine(LogisticObject object, String currentState, Emitter<ScanState> emit) {
    if (currentState == ObjectStates.retGIFzg) {
      emit(ScanObjectDetected(
        object: object,
        suggestedState: ObjectStates.finGI,
        tour: currentTour,
      ));
    } else {
      emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  // ============================================================================
  // STATE MACHINE: vehEnd (Fahrzeug Ende)
  // ============================================================================
  void _vehEndStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final currentState = object.state;
    
    switch (currentState) {
      case ObjectStates.retFailFzg:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retFailStk,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retDSFzg:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDSStk,
          tour: currentTour,
        ));
        break;
      case ObjectStates.delivery:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDSStk,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retDSEmpty:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDSStk,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retGIFzg:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retGIStk,
          tour: currentTour,
        ));
        break;
      default:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.retDSErr,
          tour: currentTour,
        ));
    }
  }

  // ============================================================================
  // STATE MACHINE: stockEnd (Lager Ende)
  // ============================================================================
  void _stockEndStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final currentState = object.state;
    
    switch (currentState) {
      case ObjectStates.retFailStk:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.finDSFail,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retDSStk:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.finDS,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retDSErr:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.finDSErr,
          tour: currentTour,
        ));
        break;
      case ObjectStates.retGIStk:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.finGITmp,
          tour: currentTour,
        ));
        break;
      default:
        emit(const ScanError(message: 'Fehler: Falscher Status'));
    }
  }

  // ============================================================================
  // STATE MACHINE: stock (Lager - HADAG)
  // ============================================================================
  void _stockStateMachine(LogisticObject object, Emitter<ScanState> emit) {
    final objectType = object.type;
    final currentState = object.state;
    final subtype = object.subtype.toLowerCase();
    
    // Only HP and GK allowed
    if (!_isTypeHP(objectType, subtype) && !_isTypeGK(objectType, subtype)) {
      emit(const ScanError(message: 'Fehler: Falscher Typ'));
      return;
    }
    
    switch (currentState) {
      case ObjectStates.unknown:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.station,
          tour: currentTour,
        ));
        break;
      case ObjectStates.stkHadag:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.station,
          tour: currentTour,
        ));
        break;
      case ObjectStates.station:
        emit(ScanObjectDetected(
          object: object,
          suggestedState: ObjectStates.stkHadag,
          tour: currentTour,
        ));
        break;
      default:
        emit(ScanUnknownObject(
          barcode: object.code,
          prefix: object.code.length >= 3 ? object.code.substring(0, 3) : '',
          tour: currentTour,
        ));
    }
  }

  // ============================================================================
  // Helper methods for type checking
  // ============================================================================
  bool _isTypeGK(int type, String subtype) {
    // GK = Geldkassette (type 1, subtypes meka, mekb, mekc, mekd, beka, bekb, bekc, bekd)
    return type == 1 || subtype.startsWith('mek') || subtype.startsWith('bek');
  }

  bool _isTypeHP(int type, String subtype) {
    // HP = Hauptkasse/Druckerpatronen (type 2, subtypes hp1a, hp1b, etc.)
    return type == 2 || subtype.startsWith('hp');
  }

  bool _isTypeFR(int type, String subtype) {
    // FR = Fahrkartenrolle (type 5, subtype fra)
    return type == 5 || subtype.startsWith('fr');
  }

  bool _isTypeSB(int type, String subtype) {
    // SB = Safebag (type 6)
    return type == 6 || subtype == 'sb';
  }

  bool _isTypeABS(int type, String subtype) {
    // ABS = Abfallbehälter (type 7)
    return type == 7 || subtype == 'abs';
  }

  bool _isTypeCNTR(int type, String subtype) {
    // CNTR = Container (type 8)
    return type == 8 || subtype.startsWith('cntr');
  }

  // ============================================================================
  // Legacy simple state machine (fallback)
  // ============================================================================
  String _determineNextState(LogisticObject object) {
    switch (object.state) {
      case ObjectStates.unknown:
        return ObjectStates.toDelivery;
      case ObjectStates.toDelivery:
        return ObjectStates.delivery;
      case ObjectStates.delivery:
        return ObjectStates.station;
      case ObjectStates.station:
        return ObjectStates.inFA;
      case ObjectStates.inFA:
        return ObjectStates.retGI;
      case ObjectStates.retGI:
        return ObjectStates.retGIFzg;
      case ObjectStates.retGIFzg:
        return ObjectStates.finGI;
      case ObjectStates.retFail:
        return ObjectStates.retFailFzg;
      case ObjectStates.retFailFzg:
        return ObjectStates.retFailStk;
      case ObjectStates.retDS:
        return ObjectStates.retDSFzg;
      case ObjectStates.retDSFzg:
        return ObjectStates.finDS;
      default:
        return object.state;
    }
  }

  // ============================================================================
  // Event handlers
  // ============================================================================
  Future<void> _onValidateBarcode(ValidateBarcode event, Emitter<ScanState> emit) async {
    if (event.barcode.isEmpty) {
      emit(const ScanValidationError(message: 'Barcode darf nicht leer sein'));
      return;
    }

    if (event.barcode.length < 6) {
      emit(const ScanValidationError(message: 'Barcode zu kurz'));
      return;
    }

    add(ProcessBarcode(barcode: event.barcode));
  }

  Future<void> _onUpdateObjectState(UpdateObjectState event, Emitter<ScanState> emit) async {
    emit(ScanProcessing(barcode: event.object.code));

    final result = await repository.updateObjectState(
      event.object.objectId,
      event.newState,
      locationId: currentTour?.locationId,
      refType: currentTour != null ? _getTourTypeCode(currentTour!.type) : null,
      refId: currentTour?.tourId,
      containerCode: event.containerCode,
    );

    result.fold(
      (failure) => emit(ScanError(message: _mapFailureToMessage(failure))),
      (_) {
        emit(ScanObjectUpdated(
          object: event.object.copyWith(state: event.newState),
          previousState: event.object.state,
          newState: event.newState,
          tour: currentTour,
        ));
      },
    );
  }

  Future<void> _onCreateUnknownObject(CreateUnknownObject event, Emitter<ScanState> emit) async {
    emit(ScanProcessing(barcode: event.barcode));

    final result = await repository.createObject(
      type: event.type,
      code: event.barcode,
    );

    result.fold(
      (failure) => emit(ScanError(message: _mapFailureToMessage(failure))),
      (_) {
        emit(ScanObjectCreated(barcode: event.barcode));
      },
    );
  }

  void _onResetScan(ResetScan event, Emitter<ScanState> emit) {
    if (currentTour != null) {
      emit(ScanReady(tour: currentTour!));
    } else {
      emit(ScanInitial());
    }
  }

  // ============================================================================
  // Helper methods
  // ============================================================================
  Map<String, String>? _findPageForBarcode(String barcode) {
    if (currentTour == null) return null;

    for (final page in currentTour!.pages) {
      if (page.code == barcode) {
        return {
          'pageId': page.pageId,
          'label': page.label ?? page.pageId,
        };
      }
      
      if (page.pageId.toLowerCase().startsWith('fsa') && page.type.isNotEmpty) {
        // FSA page detected
      }
    }
    
    return null;
  }

  bool _isValidPrefix(String prefix) {
    final validPrefixes = ['MEK', 'BEK', 'HOP', 'H1P', 'H2P', 'H3P', 'FR', 'SB', 'ABS', 'FZG'];
    return validPrefixes.any((p) => prefix.toUpperCase().startsWith(p));
  }

  int? _getTourTypeCode(String type) {
    switch (type) {
      case TourTypes.stockStart:
        return 1;
      case TourTypes.vehStart:
        return 2;
      case TourTypes.veh:
        return 3;
      case TourTypes.fsa:
        return 4;
      case TourTypes.vs:
        return 5;
      case TourTypes.gi:
        return 6;
      case TourTypes.vehEnd:
        return 7;
      case TourTypes.stockEnd:
        return 8;
      default:
        return null;
    }
  }

  String _mapFailureToMessage(Failure failure) {
    return switch (failure) {
      ServerFailure _ => 'Serverfehler: ${failure.message}',
      NetworkFailure _ => 'Netzwerkfehler. Bitte überprüfen Sie Ihre Internetverbindung.',
      NotFoundFailure _ => 'Objekt nicht gefunden',
      BarcodeFailure _ => 'Barcode-Fehler: ${failure.message}',
      _ => 'Ein Fehler ist aufgetreten: ${failure.message}',
    };
  }
}
