import 'package:dartz/dartz.dart';

import '../../../../core/errors/exceptions.dart';
import '../../../../core/errors/failures.dart';
import '../../domain/entities/user_entity.dart';
import '../../domain/repositories/users_repository.dart';
import '../datasources/users_local_datasource.dart';
import '../datasources/users_remote_datasource.dart';

/// Implementation of UsersRepository
class UsersRepositoryImpl implements UsersRepository {
  final UsersRemoteDataSource remoteDataSource;
  final UsersLocalDataSource localDataSource;

  UsersRepositoryImpl({
    required this.remoteDataSource,
    required this.localDataSource,
  });

  @override
  Future<Either<Failure, List<UserEntity>>> getUsers() async {
    try {
      // Try to get users from local storage first
      final localUsers = await localDataSource.getUsers();

      if (localUsers.isNotEmpty) {
        // Return local users if available
        return Right(localUsers.map((model) => model.toEntity()).toList());
      }

      // If no local users, fetch from API
      return await syncUsers();
    } catch (e) {
      return Left(CacheFailure(e.toString()));
    }
  }

  @override
  Future<Either<Failure, List<UserEntity>>> syncUsers() async {
    try {
      // Fetch users from API
      final users = await remoteDataSource.getUsers();

      // Save to local storage
      await localDataSource.saveUsers(users);

      // Return as entities
      return Right(users.map((model) => model.toEntity()).toList());
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      return Left(NetworkFailure(e.message));
    } catch (e) {
      return Left(ServerFailure(e.toString()));
    }
  }

  @override
  Future<Either<Failure, void>> clearUsers() async {
    try {
      await localDataSource.clearUsers();
      return const Right(null);
    } catch (e) {
      return Left(CacheFailure(e.toString()));
    }
  }
}
