import 'package:dartz/dartz.dart';
import '../../domain/entities/dashboard_entity.dart';
import '../../domain/repositories/dashboard_repository.dart';
import '../datasources/dashboard_remote_datasource.dart';
import '../models/dashboard_stats_model.dart';
import '../../../../core/error/exceptions.dart';
import '../../../../core/error/failures.dart';
import '../../../../core/network/network_info.dart';

class DashboardRepositoryImpl implements DashboardRepository {
  final DashboardRemoteDataSource remoteDataSource;
  final NetworkInfo networkInfo;

  DashboardRepositoryImpl({
    required this.remoteDataSource,
    required this.networkInfo,
  });

  @override
  Future<Either<Failure, DashboardEntity>> getDashboardData(
    String organizationId,
    String userId,
  ) async {
    if (await networkInfo.isConnected) {
      try {
        final dashboardData = await remoteDataSource.getDashboardData(organizationId, userId);
        return Right(_mapToEntity(dashboardData));
      } on ServerException catch (e) {
        return Left(ServerFailure(e.message));
      } catch (e) {
        return Left(ServerFailure('Unexpected error: $e'));
      }
    } else {
      return const Left(NetworkFailure('No internet connection'));
    }
  }

  @override
  Future<Either<Failure, DashboardStatsEntity>> getDashboardStats(
    String organizationId,
    String userId,
  ) async {
    if (await networkInfo.isConnected) {
      try {
        final stats = await remoteDataSource.getDashboardStats(organizationId, userId);
        return Right(_mapStatsToEntity(stats));
      } on ServerException catch (e) {
        return Left(ServerFailure(e.message));
      } catch (e) {
        return Left(ServerFailure('Unexpected error: $e'));
      }
    } else {
      return const Left(NetworkFailure('No internet connection'));
    }
  }

  @override
  Future<Either<Failure, List<RecentActivityEntity>>> getRecentActivities(
    String organizationId,
    String userId, {
    int limit = 10,
  }) async {
    if (await networkInfo.isConnected) {
      try {
        final activities = await remoteDataSource.getRecentActivities(
          organizationId,
          userId,
          limit: limit,
        );
        return Right(activities.map(_mapActivityToEntity).toList());
      } on ServerException catch (e) {
        return Left(ServerFailure(e.message));
      } catch (e) {
        return Left(ServerFailure('Unexpected error: $e'));
      }
    } else {
      return const Left(NetworkFailure('No internet connection'));
    }
  }

  @override
  Future<Either<Failure, List<UpcomingEventEntity>>> getUpcomingEvents(
    String organizationId,
    String userId, {
    int limit = 5,
  }) async {
    if (await networkInfo.isConnected) {
      try {
        final events = await remoteDataSource.getUpcomingEvents(
          organizationId,
          userId,
          limit: limit,
        );
        return Right(events.map(_mapEventToEntity).toList());
      } on ServerException catch (e) {
        return Left(ServerFailure(e.message));
      } catch (e) {
        return Left(ServerFailure('Unexpected error: $e'));
      }
    } else {
      return const Left(NetworkFailure('No internet connection'));
    }
  }

  // Mappers
  DashboardEntity _mapToEntity(DashboardDataModel model) {
    return DashboardEntity(
      stats: _mapStatsToEntity(model.stats),
      recentActivities: model.recentActivities.map(_mapActivityToEntity).toList(),
      upcomingEvents: model.upcomingEvents.map(_mapEventToEntity).toList(),
      userPreferences: model.userPreferences,
      organizationId: model.organizationId,
      userId: model.userId,
    );
  }

  DashboardStatsEntity _mapStatsToEntity(DashboardStatsModel model) {
    return DashboardStatsEntity(
      totalMembers: model.totalMembers,
      activeMembers: model.activeMembers,
      totalEvents: model.totalEvents,
      upcomingEvents: model.upcomingEvents,
      totalContributions: model.totalContributions,
      totalContributionAmount: model.totalContributionAmount,
      pendingRequests: model.pendingRequests,
      completedProjects: model.completedProjects,
      monthlyGrowth: model.monthlyGrowth,
      engagementRate: model.engagementRate,
      lastUpdated: model.lastUpdated,
    );
  }

  RecentActivityEntity _mapActivityToEntity(RecentActivityModel model) {
    return RecentActivityEntity(
      id: model.id,
      type: model.type,
      title: model.title,
      description: model.description,
      userAvatar: model.userAvatar,
      userName: model.userName,
      timestamp: model.timestamp,
      actionUrl: model.actionUrl,
      metadata: model.metadata,
    );
  }

  UpcomingEventEntity _mapEventToEntity(UpcomingEventModel model) {
    return UpcomingEventEntity(
      id: model.id,
      title: model.title,
      description: model.description,
      startDate: model.startDate,
      endDate: model.endDate,
      location: model.location,
      maxParticipants: model.maxParticipants,
      currentParticipants: model.currentParticipants,
      status: model.status,
      imageUrl: model.imageUrl,
      tags: model.tags,
    );
  }
}
