import 'package:flutter/material.dart'; import 'package:pshared/api/responses/verification/response.dart'; import 'package:pshared/provider/resource.dart'; import 'package:pshared/service/verification.dart'; import 'package:pshared/utils/exception.dart'; class PayoutVerificationProvider extends ChangeNotifier { Resource _resource = Resource(data: null); DateTime? _cooldownUntil; VerificationResponse? get response => _resource.data; bool get isLoading => _resource.isLoading; Exception? get error => _resource.error; String get target => _resource.data?.target ?? ''; String? get idempotencyKey => _resource.data?.idempotencyKey; DateTime? get cooldownUntil => _cooldownUntil; Future requestCode() async { _setResource(_resource.copyWith(isLoading: true, error: null)); try { final response = await VerificationService.requestPayoutCode(); _cooldownUntil = _resolveCooldownUntil(response); _setResource(_resource.copyWith( data: response, isLoading: false, error: null, )); return response; } catch (e) { _setResource(_resource.copyWith( isLoading: false, error: toException(e), )); rethrow; } } Future resendCode() async { final currentKey = _resource.data?.idempotencyKey; if (currentKey == null || currentKey.isEmpty) { throw StateError('Payout verification is not initialized'); } _setResource(_resource.copyWith(isLoading: true, error: null)); try { final response = await VerificationService.resendPayoutCode( idempotencyKey: currentKey, ); _cooldownUntil = _resolveCooldownUntil(response); _setResource(_resource.copyWith( data: response, isLoading: false, error: null, )); return response; } catch (e) { _setResource(_resource.copyWith( isLoading: false, error: toException(e), )); rethrow; } } Future confirmCode(String code) async { final currentKey = _resource.data?.idempotencyKey; if (currentKey == null || currentKey.isEmpty) { throw StateError('Payout verification is not initialized'); } _setResource(_resource.copyWith(isLoading: true, error: null)); try { await VerificationService.confirmPayoutCode( code: code.trim(), idempotencyKey: currentKey, ); _setResource(_resource.copyWith(isLoading: false, error: null)); } catch (e) { _setResource(_resource.copyWith( isLoading: false, error: toException(e), )); rethrow; } } void reset() { _cooldownUntil = null; _setResource(Resource(data: null)); } DateTime? _resolveCooldownUntil(VerificationResponse response) { if (response.cooldownSeconds <= 0) return null; return DateTime.now().add(response.cooldownDuration); } void _setResource(Resource resource) { _resource = resource; notifyListeners(); } }