// lib/presentation/auth/bloc/auth_bloc.dart import 'package:bloc/bloc.dart'; import 'package:dio/dio.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:meta/meta.dart'; import 'package:proxibuy/core/config/api_config.dart'; part 'auth_event.dart'; part 'auth_state.dart'; class AuthBloc extends Bloc { late final Dio _dio; final _storage = const FlutterSecureStorage(); AuthBloc() : super(AuthInitial()) { _dio = Dio(); _dio.interceptors.add( LogInterceptor( requestHeader: true, requestBody: true, responseBody: true, error: true, ), ); on(_onCheckAuthStatus); on(_onSendOTP); on(_onVerifyOTP); on(_onUpdateUserInfo); on(_onLogout); } Future _onCheckAuthStatus( CheckAuthStatusEvent event, Emitter emit) async { final token = await _storage.read(key: 'accessToken'); if (token != null && token.isNotEmpty) { emit(AuthSuccess()); } else { emit(AuthInitial()); } } Future _onSendOTP(SendOTPEvent event, Emitter emit) async { emit(AuthLoading()); try { final response = await _dio.post( ApiConfig.baseUrl + ApiConfig.sendCode, data: {'Phone': event.phoneNumber, 'Code': event.countryCode}, ); if (isClosed) return; if (response.statusCode == 200) { emit(AuthCodeSentSuccess( phone: event.phoneNumber, countryCode: event.countryCode, )); } else { emit(AuthFailure(response.data['message'] ?? 'خطایی رخ داد')); } } on DioException catch (e) { if (isClosed) return; emit(AuthFailure(e.response?.data['message'] ?? 'خطا در ارتباط با سرور')); } } Future _onVerifyOTP(VerifyOTPEvent event, Emitter emit) async { emit(AuthLoading()); try { final response = await _dio.post( ApiConfig.baseUrl + ApiConfig.verifyCode, data: { 'Phone': event.phoneNumber, 'Code': event.countryCode, 'OTP': event.otp, }, ); if (isClosed) return; if (response.statusCode == 200) { final accessToken = response.data['data']['accessToken']; final refreshToken = response.data['data']['refreshToken']; final userID = response.data['data']['ID']; await _storage.write(key: 'accessToken', value: accessToken); await _storage.write(key: 'refreshToken', value: refreshToken); await _storage.write(key: 'userID', value: userID); emit(AuthNeedsInfo()); } else { emit(AuthFailure(response.data['message'] ?? 'کد صحیح نیست')); } } on DioException catch (e) { if (isClosed) return; emit(AuthFailure(e.response?.data['message'] ?? 'خطایی در سرور رخ داد')); } } Future _onUpdateUserInfo( UpdateUserInfoEvent event, Emitter emit) async { debugPrint("AuthBloc: 🔵 ایونت UpdateUserInfoEvent دریافت شد با نام: ${event.name}"); emit(AuthLoading()); try { final token = await _storage.read(key: 'accessToken'); if (token == null) { debugPrint("AuthBloc: 🔴 خطا: توکن کاربر یافت نشد."); emit(const AuthFailure("شما وارد نشده‌اید.")); return; } debugPrint("AuthBloc: 🟡 در حال ارسال درخواست آپدیت به سرور..."); final response = await _dio.post( ApiConfig.baseUrl + ApiConfig.updateUser, data: {'Name': event.name, 'Gender': event.gender}, options: Options(headers: {'Authorization': 'Bearer $token'}), ); debugPrint("AuthBloc: 🟠 پاسخ سرور دریافت شد. StatusCode: ${response.statusCode}"); if (isClosed) { debugPrint("AuthBloc: 🔴 خطا: BLoC قبل از اتمام عملیات بسته شده است."); return; } if (response.statusCode == 200) { debugPrint("AuthBloc: ✅ درخواست موفق بود. در حال emit کردن AuthSuccess..."); emit(AuthSuccess()); } else { debugPrint("AuthBloc: 🔴 سرور پاسخ ناموفق داد: ${response.data['message']}"); emit(AuthFailure(response.data['message'] ?? 'خطا در ثبت اطلاعات')); } } on DioException catch (e) { debugPrint("AuthBloc: 🔴 خطای DioException رخ داد: ${e.response?.data['message']}"); if (isClosed) return; emit(AuthFailure(e.response?.data['message'] ?? 'خطا در ارتباط با سرور')); } } Future _onLogout(LogoutEvent event, Emitter emit) async { await _storage.deleteAll(); emit(AuthInitial()); } }