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

import '../../../common/data/refund_data.dart';
import '../../../domain/order/order.dart';

part 'refund_form_event.dart';
part 'refund_form_state.dart';
part 'refund_form_bloc.freezed.dart';

@injectable
class RefundFormBloc extends Bloc<RefundFormEvent, RefundFormState> {
  final IOrderRepository _repository;
  RefundFormBloc(this._repository) : super(RefundFormState.initial()) {
    on<RefundFormEvent>(_onRefundFormEvent);
  }

  Future<void> _onRefundFormEvent(
    RefundFormEvent event,
    Emitter<RefundFormState> emit,
  ) {
    return event.map(
      setOrder: (e) async {
        emit(state.copyWith(order: e.order));
      },
      reasonChanged: (e) async {
        emit(state.copyWith(reason: e.reason));
      },
      refundReasonChanged: (e) async {
        emit(state.copyWith(refundReason: e.refundReason));
      },
      submitted: (e) async {
        Either<OrderFailure, Unit>? failureOrRefund;

        // Generate new idempotency key saat user intent (tap Refund)
        // Kalau sedang retry, pakai key yang sama
        final idempotencyKey = state.idempotencyKey ?? const Uuid().v4();

        emit(state.copyWith(
          isSubmitting: true,
          failureOrRefund: none(),
          idempotencyKey: idempotencyKey,
        ));

        failureOrRefund = await _repository.refundOrder(
          id: state.order.id,
          reason: state.refundReason?.value == 'Lainnya'
              ? state.reason
              : state.refundReason?.value ?? '',
          refundAmount: state.order.totalAmount,
          idempotencyKey: idempotencyKey,
        );

        emit(
          state.copyWith(
            isSubmitting: false,
            failureOrRefund: optionOf(failureOrRefund),
            // Clear key on success, keep on failure for retry
            idempotencyKey: failureOrRefund.isRight() ? null : idempotencyKey,
          ),
        );
      },
    );
  }
}
