import 'package:bloc/bloc.dart';
import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';

import '../../../common/function/app_function.dart';
import '../../../domain/printer/printer.dart';

part 'printer_form_event.dart';
part 'printer_form_state.dart';
part 'printer_form_bloc.freezed.dart';

@injectable
class PrinterFormBloc extends Bloc<PrinterFormEvent, PrinterFormState> {
  final IPrinterRepository _printerRepository;
  PrinterFormBloc(this._printerRepository) : super(PrinterFormState.initial()) {
    on<PrinterFormEvent>(_onPrinterFormEvent);
  }

  Future<void> _onPrinterFormEvent(
    PrinterFormEvent event,
    Emitter<PrinterFormState> emit,
  ) {
    return event.map(
      codeChanged: (e) async {
        emit(state.copyWith(code: e.code));
      },
      nameChanged: (e) async {
        emit(state.copyWith(name: e.name));
      },
      addressChanged: (e) async {
        emit(state.copyWith(address: e.address));
      },
      typeChanged: (e) async {
        emit(state.copyWith(type: e.type));
      },
      paperChanged: (e) async {
        emit(state.copyWith(paper: e.paper));
      },
      created: (e) async {
        Either<PrinterFailure, Unit> failureOrPrinter;

        emit(state.copyWith(isCreating: true, failureOrCreateSuccess: none()));

        final request = Printer(
          id: generateRandomNumber(),
          code: state.code,
          name: state.name,
          address: state.address,
          paper: state.paper,
          type: state.type,
          createdAt: DateTime.now(),
          updatedAt: DateTime.now(),
        );

        failureOrPrinter = await _printerRepository.createPrinter(request);

        emit(
          state.copyWith(
            isCreating: false,
            failureOrCreateSuccess: optionOf(failureOrPrinter),
          ),
        );
      },
      updated: (e) async {
        Either<PrinterFailure, Unit> failureOrPrinter;

        emit(state.copyWith(isUpdate: true, failureOrUpdateSuccess: none()));

        final request = Printer(
          id: generateRandomNumber(),
          code: state.code,
          name: state.name,
          address: state.address,
          paper: state.paper,
          type: state.type,
          createdAt: DateTime.now(),
          updatedAt: DateTime.now(),
        );

        failureOrPrinter = await _printerRepository.updatePrinter(
          request,
          e.id,
        );

        emit(
          state.copyWith(
            isUpdate: false,
            failureOrUpdateSuccess: optionOf(failureOrPrinter),
          ),
        );
      },
    );
  }
}
