# هيكلية المشروع (Project Architecture)

هذا المشروع يتبع نمط Clean Architecture مع فصل واضح بين الطبقات.

## الهيكلية العامة

```
lib/
├── core/                    # المكونات الأساسية المشتركة
│   ├── constants/          # الثوابت (مثل الأبعاد)
│   ├── di/                 # Dependency Injection (GetIt)
│   ├── enums/              # التعدادات
│   ├── error/              # معالجة الأخطاء (Exceptions & Failures)
│   ├── network/            # عميل API (ApiClient)
│   └── utils/              # الأدوات المساعدة
│
├── data/                    # طبقة البيانات
│   ├── datasources/        # مصادر البيانات (Remote & Local)
│   ├── dto/                # Data Transfer Objects (للاتصال مع API)
│   └── repositories/       # تطبيقات الـ Repositories
│
├── domain/                  # طبقة الأعمال (Business Logic)
│   ├── models/             # نماذج الأعمال
│   ├── repositories/       # واجهات الـ Repositories
│   └── usecases/           # حالات الاستخدام (Use Cases)
│
├── presentation/            # طبقة العرض
│   ├── blocs/              # State Management (BLoC)
│   ├── screens/            # الشاشات
│   └── widgets/            # الويدجتات القابلة لإعادة الاستخدام
│
├── models/                  # النماذج القديمة (يمكن نقلها لـ domain/models)
├── screens/                 # الشاشات القديمة (يمكن نقلها لـ presentation/screens)
├── services/                # الخدمات القديمة
└── widgets/                 # الويدجتات القديمة (يمكن نقلها لـ presentation/widgets)
```

## كيفية الاستخدام

### 1. إضافة API جديد

#### أ) إنشاء DTO في `data/dto/`
```dart
class LoginDto {
  final String phoneNumber;
  final String password;
  
  LoginDto({required this.phoneNumber, required this.password});
  
  Map<String, dynamic> toJson() => {
    'phoneNumber': phoneNumber,
    'password': password,
  };
}
```

#### ب) إنشاء Remote Data Source في `data/datasources/`
```dart
abstract class AuthRemoteDataSource {
  Future<LoginResponseDto> login(LoginDto dto);
}

class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
  final ApiClient apiClient;
  
  AuthRemoteDataSourceImpl({required this.apiClient});
  
  @override
  Future<LoginResponseDto> login(LoginDto dto) async {
    try {
      final response = await apiClient.post('/Auth/login', data: dto.toJson());
      // Handle response
    } on DioException catch (e) {
      // Handle errors
    }
  }
}
```

#### ج) إنشاء Repository Interface في `domain/repositories/`
```dart
abstract class AuthRepository {
  Future<Either<Failure, LoginResponseModel>> login(LoginRequest request);
}
```

#### د) إنشاء Repository Implementation في `data/repositories/`
```dart
class AuthRepositoryImpl implements AuthRepository {
  final AuthRemoteDataSource remoteDataSource;
  
  AuthRepositoryImpl({required this.remoteDataSource});
  
  @override
  Future<Either<Failure, LoginResponseModel>> login(LoginRequest request) async {
    try {
      final dto = LoginDto(...);
      final responseDto = await remoteDataSource.login(dto);
      final model = _convertDtoToModel(responseDto);
      return Right(model);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    }
  }
}
```

#### هـ) إنشاء Use Case في `domain/usecases/`
```dart
class LoginUseCase {
  final AuthRepository repository;
  
  LoginUseCase({required this.repository});
  
  Future<Either<Failure, LoginResponseModel>> call(LoginRequest request) {
    return repository.login(request);
  }
}
```

#### و) تسجيل في `core/di/injection_container.dart`
```dart
// Data source
sl.registerLazySingleton<AuthRemoteDataSource>(
  () => AuthRemoteDataSourceImpl(apiClient: sl()),
);

// Repository
sl.registerLazySingleton<AuthRepository>(
  () => AuthRepositoryImpl(remoteDataSource: sl()),
);

// Use case
sl.registerLazySingleton(() => LoginUseCase(repository: sl()));
```

### 2. استخدام في BLoC
```dart
class LoginBloc extends Bloc<LoginEvent, LoginState> {
  final LoginUseCase loginUseCase;
  
  LoginBloc({required this.loginUseCase}) : super(LoginInitial()) {
    on<LoginSubmitted>(_onLoginSubmitted);
  }
  
  Future<void> _onLoginSubmitted(
    LoginSubmitted event,
    Emitter<LoginState> emit,
  ) async {
    emit(LoginLoading());
    final result = await loginUseCase(event.request);
    result.fold(
      (failure) => emit(LoginError(failure.message)),
      (response) => emit(LoginSuccess(response)),
    );
  }
}
```

## الحزم المستخدمة

- `dio`: للاتصال بالـ API
- `get_it`: لإدارة Dependency Injection
- `dartz`: لاستخدام `Either` للتعامل مع الأخطاء
- `equatable`: للمساواة بين الكائنات
- `shared_preferences`: للتخزين المحلي

## ملاحظات مهمة

1. **تحديث baseUrl**: قم بتحديث `baseUrl` في `core/network/api_client.dart`
2. **إضافة Token**: يمكن إضافة interceptor في `ApiClient` لإضافة token تلقائياً
3. **معالجة الأخطاء**: جميع الأخطاء تمر عبر `Exceptions` ثم `Failures`
4. **التحويل**: DTOs للـ API، Models للـ Domain
