import 'package:dartz/dartz.dart';
import '../../core/error/exceptions.dart';
import '../../core/error/failures.dart';
import '../datasources/vacation_remote_data_source.dart';
import '../dto/vacation_request_dto.dart';
import '../../domain/models/vacation_request.dart';
import '../../domain/models/vacation_response_model.dart';
import '../../domain/models/vacation_type_model.dart';
import '../../domain/models/vacations_list_response_model.dart';
import '../../domain/repositories/vacation_repository.dart';

class VacationRepositoryImpl implements VacationRepository {
  final VacationRemoteDataSource remoteDataSource;

  VacationRepositoryImpl({required this.remoteDataSource});

  @override
  Future<Either<Failure, VacationResponseModel>> createVacation(
    VacationRequest request,
  ) async {
    try {
      final dto = VacationRequestDto(
        employeeId: request.employeeId,
        startDate: request.startDate,
        endDate: request.endDate,
        reason: request.reason,
        type: request.type,
      );

      final responseDto = await remoteDataSource.createVacation(dto);

      // Convert DTO to Model
      final responseModel = VacationResponseModel(
        statusCode: responseDto.statusCode,
        isSuccess: responseDto.isSuccess,
        message: responseDto.message,
        data: responseDto.data != null
            ? VacationDataModel(
                employeeId: responseDto.data!.employeeId,
                employeeFullName: responseDto.data!.employeeFullName,
                startDate: responseDto.data!.startDate,
                endDate: responseDto.data!.endDate,
                reason: responseDto.data!.reason,
                submittedBy: responseDto.data!.submittedBy,
                submittedByUser: responseDto.data!.submittedByUser,
                state: responseDto.data!.state,
                type: responseDto.data!.type,
                id: responseDto.data!.id,
                createdAt: responseDto.data!.createdAt,
                updatedAt: responseDto.data!.updatedAt,
                deletedAt: responseDto.data!.deletedAt,
                isDeleted: responseDto.data!.isDeleted,
              )
            : null,
      );

      return Right(responseModel);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      return Left(NetworkFailure(e.message));
    } catch (e) {
      return Left(ServerFailure('خطأ غير متوقع: $e'));
    }
  }

  @override
  Future<Either<Failure, VacationTypesResponseModel>> getVacationTypes() async {
    try {
      final responseDto = await remoteDataSource.getVacationTypes();

      // Convert DTO to Model
      final responseModel = VacationTypesResponseModel(
        statusCode: responseDto.statusCode,
        isSuccess: responseDto.isSuccess,
        message: responseDto.message,
        data: responseDto.data
            .map((dto) => VacationTypeModel(
                  value: dto.value,
                  name: dto.name,
                ))
            .toList(),
      );

      return Right(responseModel);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      return Left(NetworkFailure(e.message));
    } catch (e) {
      return Left(ServerFailure('خطأ غير متوقع: $e'));
    }
  }

  @override
  Future<Either<Failure, VacationsListResponseModel>> getVacations() async {
    try {
      final responseDto = await remoteDataSource.getVacations();

      // Convert DTO to Model
      final responseModel = VacationsListResponseModel(
        statusCode: responseDto.statusCode,
        isSuccess: responseDto.isSuccess,
        message: responseDto.message,
        data: responseDto.data != null
            ? VacationsListDataModel(
                items: responseDto.data!.items
                    .map((dto) => VacationDataModel(
                          employeeId: dto.employeeId,
                          employeeFullName: dto.employeeFullName,
                          startDate: dto.startDate,
                          endDate: dto.endDate,
                          reason: dto.reason,
                          submittedBy: dto.submittedBy,
                          submittedByUser: dto.submittedByUser,
                          state: dto.state,
                          type: dto.type,
                          id: dto.id,
                          createdAt: dto.createdAt,
                          updatedAt: dto.updatedAt,
                          deletedAt: dto.deletedAt,
                          isDeleted: dto.isDeleted,
                        ))
                    .toList(),
                pageNumber: responseDto.data!.pageNumber,
                pageSize: responseDto.data!.pageSize,
                totalCount: responseDto.data!.totalCount,
                totalPages: responseDto.data!.totalPages,
              )
            : null,
      );

      return Right(responseModel);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      return Left(NetworkFailure(e.message));
    } catch (e) {
      return Left(ServerFailure('خطأ غير متوقع: $e'));
    }
  }
}
